我正在使用getopt
读取命令行参数,而我正在使用.
读取配置文件:
test.sh:
#!/bin/bash
set -- `getopt C:a:b:c: "$@"`
C="default.cfg"
. $C
while [ $# -gt 0 ]; do
case "$1" in
-a) cfg1="$2"; shift;;
-b) cfg2="$2"; shift;;
-c) cfg3="$2"; shift;;
-C) C="$2"; #you'll see what this is for later
shift;;
--) shift;
break;;
-*) echo "invalid option";
exit 1;;
*) break;;
esac
shift
done
echo "cfg1 = $cfg1"
echo "cfg2 = $cfg2"
echo "cfg3 = $cfg3"
exit 0
default.cfg中::
cfg1=hello
cfg2=there
cfg3=friend
这一切都按预期工作:
$ ./test.sh
cfg1 = hello
cfg2 = there
cfg3 = friend
$ ./test.sh -b optional
cfg1 = hello
cfg2 = optional
cfg3 = friend
这个问题是我希望以下列方式对配置进行优先排序:
-C
选项所以,如果我有这个:
test.cfg:
cfg1=custom_file_1
cfg2=custom_file_2
我想得到这个:
$ ./test.sh -b command_line -C test.cfg
cfg1 = custom_file_1
cfg2 = command_line
cfg3 = friend
我无法弄清楚如何加载默认配置文件,然后搜索-C
的选项,然后加载自定义配置文件,覆盖默认值,然后搜索命令行参数AGAIN并覆盖再次配置。我是shell脚本的新手,所以请原谅我,如果我错过了一些明显的东西。
答案 0 :(得分:1)
要覆盖变量,请尝试替换:
-C) C="$2";
with:
-C) . "$2";
并用:
调用它./test.sh -C test.cfg -a command_line1 -b command_line2
更新:
对于任何顺序的选项,您可以尝试:
C="default.cfg"
. $C
while getopts C:a:b:c: OPTION
do
case $OPTION in
a) cfg1_override=$OPTARG;;
b) cfg2_override=$OPTARG;;
c) cfg3_override=$OPTARG ;;
C) . $OPTARG;;
-) break;;
-*) echo "invalid option";
exit 1;;
*) break;;
esac
done
shift $(($OPTIND - 1))
cfg1="${cfg1_override-${cfg1}}"
cfg2="${cfg2_override-${cfg2}}"
cfg3="${cfg3_override-${cfg3}}"
echo "cfg1 = $cfg1"
echo "cfg2 = $cfg2"
echo "cfg3 = $cfg3"
exit 0
基于Is it possible to specify the order getopts conditions are executed?
答案 1 :(得分:1)
您可以预处理参数并提取您正在寻找的值:
#!/bin/bash
args=$(getopt C:a:b:c: "$@")
eval set -- $args
conf="default.cfg"
source "$conf"
# pre-process the arguments and see if we can find -C
found=0
for opt in "$@"; do
if [[ $found -eq 1 ]] && [[ -f "$opt" ]]; then
source "$opt"
break
fi
if [[ "$opt" == "-C" ]]; then
found=1
fi
done
while [ $# -gt 0 ]; do
case "$1" in
-a) cfg1="$2"; shift;;
-b) cfg2="$2"; shift;;
-c) cfg3="$2"; shift;;
-C) shift;; #don't do anything with this
--) shift;
break;;
-*) echo "invalid option";
exit 1;;
*) break;;
esac
shift
done
echo "cfg1 = $cfg1"
echo "cfg2 = $cfg2"
echo "cfg3 = $cfg3"
exit 0
答案 2 :(得分:0)
第一个来源default.cfg。 比扫描-C选项的选项。找到后处理这个。 最后使用getopts并在getopts中找到它时跳过-C。