是否有可能指定的顺序getopts的条件执行? [英] Is it possible to specify the order getopts conditions are executed?
问题描述
在bash脚本,我想从一个配置文件加载设置,并覆盖使用命令行选项单独设置。在设置无论是在配置文件中,也对命令行中指定的情况下,命令行设置应采取precedence。
In a bash script, I'd like to load settings from a config file and override individual settings with command-line options. In cases where a setting is specified both in the config file and also on the command line, the command-line setting should take precedence.
您如何确保其他getopts的块之前的配置文件被加载?下面是我得到了什么:
How do you ensure the config file is loaded before the other getopts blocks? Here's what I've got:
#!/bin/bash
# ...
while getopts "c:l:o:b:dehruwx" OPTION
do
case $OPTION in
c)
echo "load"
CONFIG_FILE=$OPTARG
# load_config is a function that sources the config file
load_config $CONFIG_FILE
;;
l)
echo "set local"
LOCAL_WAR_FILE=$OPTARG
;;
# ...
esac
done
shift $(($OPTIND - 1))
不管是为了我把处理程序-c选项,它总是加载配置文件后,其他选项的设置。这使得更多的是痛苦与命令行选项合并的配置文件的设置。
No matter what order I put the handler for the -c option, it always loads the config file AFTER the other options are set. This makes it more of a pain to merge the config file settings with the command-line options.
推荐答案
每个调用 getopts的
始终处理下一个选项(如通过检查<$ C $确定C> $ OPTIND ),所以你的,而
-loop必然过程,它们出现的顺序选择。
Each call to getopts
always processes the "next" option (as determined by examining $OPTIND
), so your while
-loop will necessarily process the options in the order they appear.
由于您希望 -c
来部分地被其他选项取代,即使是在他们之后出现在命令行中,有可以采取一些办法。
Since you want -c
to be partly superseded by other options, even if it appears after them on the command-line, there are a few approaches you can take.
一是遍历所有的选项两次的:
One is to loop over the options twice:
#!/bin/bash
# ...
optstring='c:l:o:b:dehruwx'
while getopts "$optstring" OPTION
do
case $OPTION in
c)
echo "load"
CONFIG_FILE=$OPTARG
# load_config is a function that sources the config file
load_config $CONFIG_FILE
esac
done
OPTIND=1
while getopts "$optstring" OPTION
do
case $OPTION in
l)
echo "set local"
LOCAL_WAR_FILE=$OPTARG
;;
# ...
esac
done
shift $(($OPTIND - 1))
另一个是保存在变量选项 -c
的不会的覆盖,然后将其复制过来:
Another is to save options in variables that -c
won't override, and then copy them over:
#!/bin/bash
# ...
while getopts c:l:o:b:dehruwx OPTION
do
case $OPTION in
c)
echo "load"
CONFIG_FILE=$OPTARG
# load_config is a function that sources the config file
load_config $CONFIG_FILE
;;
l)
echo "set local"
LOCAL_WAR_FILE_OVERRIDE=$OPTARG
;;
# ...
esac
done
shift $(($OPTIND - 1))
LOCAL_WAR_FILE="${LOCAL_WAR_FILE_OVERRIDE-${LOCAL_WAR_FILE}}"
(或者相反,配置文件可以设置类似 LOCAL_WAR_FILE_DEFAULT
选项,然后你会写 LOCAL_WAR_FILE =$ {$ LOCAL_WAR_FILE- {LOCAL_WAR_FILE_DEFAULT}}
)
另一种选择是要求 -c
,如果present,来的第一个的。您可以先处理自己做的是:
Another option is to require that -c
, if present, come first. You can do that by handling it first yourself:
if [[ "$1" = -c ]] ; then
echo "load"
CONFIG_FILE="$2"
# load_config is a function that sources the config file
load_config "$CONFIG_FILE"
shift 2
fi
,然后在你的主,而
-loop,只需办理 -c
通过打印错误信息。
and then in your main while
-loop, just handle -c
by printing an error message.
另一种方法是简单地记录您的现有行为,并称之为一个功能。很多Unix工具有后来的选项取代较早的,所以这种行为是不是一个真正的问题。
Another is simply to document your existing behavior and call it a "feature". A lot of Unix utilities have later options supersede earlier ones, so this behavior isn't really a problem.
这篇关于是否有可能指定的顺序getopts的条件执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!