是否可以指定执行getopts条件的顺序?

Tra*_*ear 2 bash shell

在bash脚本中,我想从配置文件加载设置,并使用命令行选项覆盖各个设置.如果在配置文件和命令行中同时指定了设置,则命令行设置应优先.

如何确保在其他getopts块之前加载配置文件?这是我得到的:

#!/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))
Run Code Online (Sandbox Code Playgroud)

无论我为-c选项设置处理程序的顺序如何,它总是在设置其他选项之后加载配置文件.这使得将配置文件设置与命令行选项合并更加困难.

rua*_*akh 9

每次调用getopts总是处理"下一个"选项(由检查确定$OPTIND),因此您的while-loop必须按照它们出现的顺序处理选项.

由于您希望-c被其他选项部分取代,即使它出现在命令行之后,您也可以采取一些方法.

一种是将选项循环两次:

#!/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))
Run Code Online (Sandbox Code Playgroud)

另一种方法是将选项保存在-c 不会覆盖的变量中,然后将它们复制到:

#!/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}}"
Run Code Online (Sandbox Code Playgroud)

(或者,相反,配置文件可以设置类似的选项LOCAL_WAR_FILE_DEFAULT,然后你就可以了LOCAL_WAR_FILE="${LOCAL_WAR_FILE-${LOCAL_WAR_FILE_DEFAULT}}".)

另一种选择是要求-c,如果存在,首先.你可以先自己处理它:

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
Run Code Online (Sandbox Code Playgroud)

然后在你的主while循环中,只需-c通过打印错误消息来处理.

另一个是简单地记录您现有的行为并将其称为"功能".很多Unix实用程序后来的选项都取代了之前的选项,所以这种行为并不是真正的问题.