2

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))

-cオプションのハンドラーをどのような順序で配置しても、他のオプションが設定された後は常に構成ファイルがロードされます。これにより、構成ファイルの設定をコマンドラインオプションとマージするのがさらに面倒になります。

4

2 に答える 2

9

への各呼び出しはgetopts常に「次の」オプションを処理するため ( を調べることで決定$OPTIND)、while-loop は必ずオプションを表示される順序で処理します。

-cコマンドラインで他のオプションの後に表示されたとしても、他のオプションに部分的に取って代わられる必要があるため、いくつかの方法があります。

1 つは、オプションを2 回ループすることです。

#!/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))

もう 1 つは、オーバーライドし-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}}"

(または、逆に、構成ファイルで のようなオプションを設定できます。LOCAL_WAR_FILE_DEFAULT次に、 と記述しLOCAL_WAR_FILE="${LOCAL_WAR_FILE-${LOCAL_WAR_FILE_DEFAULT}}"ます。)

もう 1 つのオプションは、 が存在する場合、最初-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

次に、メインwhileループで-c、エラーメッセージを出力して処理します。

もう 1 つは、単に既存の動作を文書化し、それを「機能」と呼ぶことです。多くの Unix ユーティリティには、以前のオプションに取って代わる新しいオプションがあるため、この動作は実際には問題になりません。

于 2013-02-26T18:20:23.340 に答える
1

構成ファイルにプログラムのデフォルトオプションが含まれていると仮定すると、同等のコマンドラインオプションで上書きされない限り、常にデフォルトでこれらのオプションを使用する必要があります。これは合理的です。あなたの場合、最初に設定ファイルをソース/ロードしてから、コマンドラインオプションを解析し、parseopts必要に応じてループ内でそれらに新しい値を割り当てます。

于 2013-02-26T00:29:17.227 に答える