シェルスクリプトでスイッチを処理するにはどうすればよいですか?

-x--xxxxは引数ではなくスイッチとして使用しますか、それともすべての入力変数を調べてダッシュをテストし、その後引数を解析する必要がありますか?

回答

getopts を使用します。

かなりですPOSIX仕様のままポータブル。残念ながら、長いオプションはサポートされていません。

こちらのgetopts チュートリアルもご覧ください。 bash-hackerswikiとstackoverflowからのこの質問

短いオプションのみが必要な場合は、(非サイレントエラーレポートを使用)は次のとおりです:

# process arguments "$1", "$2", ... (i.e. "$@") while getopts "ab:" opt; do case $opt in a) aflag=true ;; # Handle -a b) barg=$OPTARG ;; # Handle -b argument \?) ;; # Handle error: unknown option or missing required argument. esac done 

コメント

  • getoptは使用する前に常にGNUgetoptとして確認する必要がありますが、とにかく使用しないでください' getoptsはとにかく移植性が高い(そして一般的には優れている)ので。何らかの理由で呼び出す必要がある場合は、GNU固有の方法で呼び出します。 GETOPT_COMPATIBLEが環境内にないことを確認してください。
  • while getopts "ab:" optのコロンは何をしますか?
  • @ user394オプション文字の後の:は、それを示します引数が必要です。最初の文字としての:は、エラーメッセージを抑制することを意味します。

回答

「bashなどを使用していると思います。例:

all=false long=false while getopts ":hal" option; do case $option in h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;; a) all=true ;; l) long=true ;; ?) echo "error: option -$OPTARG is not implemented"; exit ;; esac done # remove the options from the positional parameters shift $(( OPTIND - 1 )) ls_opts=() $all && ls_opts+=( -a ) $long && ls_opts+=( -l ) # now, do it ls "${ls_opts[@]}" "$@" 

コメント

  • +1(+=を配列で使用)。'それができるとは知らなかった。いいね!

回答

パラメータを解析するには、サイクルを作成する必要があります。実際、getoptsコマンド。

これは、getoptsマニュアルページの簡単な例です:

aflag= bflag= while getopts ab: name do case $name in a) aflag=1;; b) bflag=1 bval="$OPTARG";; ?) printf "Usage: %s: [-a] [-b value] args\n" $0 exit 2;; esac done if [ ! -z "$aflag" ]; then printf "Option -a specified\n" fi if [ ! -z "$bflag" ]; then printf "Option -b "%s" specified\n" "$bval" fi shift $(($OPTIND - 1)) printf "Remaining arguments are: %s\n" "$*" 

回答

最近、用途が広く、複数の種類のスイッチを任意の順序で使用できるスクリプトを作成しました。できません。明らかな法的理由で完全なスクリプトを開示します(言うまでもなく、現時点では私はそれを持っていません)が、ここにその要点があります。 nサブルーチンを作成し、スクリプトの最後で呼び出します。

options () { if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist while (( "$#" )); do # process ALL arguments if [ "$1" = ^-t$ ]; then # -t short for "test" # do something here THEN shift the argument # shift removes it from $@ and reduces $# by # one if you supply no argument shift # we can also process multiple arguments at once elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments # do something more then remove them ALL from the arg list shift 3 else echo "No matching arguments!" echo "Usage: [script options list here]" fi done else echo "Usage: [script options list here]" exit 0 fi } options "$@" # run options and loop through/process ALL arguments 

bashスクリプトを400行/ 15k文字未満に制限することをお勧めします。私の前述のスクリプトはこのサイズを超えて大きくなり、作業が非常に困難になりました。私はそれをPerlで書き直し始めました。これは、このタスクにより適しています。 bashでスクリプトを操作するときは、このことを覚えておいてください。 Bashは小さなスクリプトやワンライナーに最適ですが、もっと複雑なものは「Perlで書くほうがいいです。

注:上記をテストしていないので、おそらく機能しませんが、

コメント

  • 最後にoptionsを呼び出す方法正しくない場合は、-bash: syntax error near unexpected token $@が返されます。options "$@"と呼びます。
  • うん、PerlとBash。修正済み。
  • そのwhile条件を(($#))にするべきではないのですか?
  • 理由$#に2セットの括弧が必要ですか?編集:'正しいです。while (( "$#" ))

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です