16

getopt(not ) を使用getopsして、bash スクリプトがオプションとスイッチ (長い --option と短い -o 形式の両方) を処理できるようにしています。

無効なオプションをトラップして処理できるようにしたいと考えています。通常、ユーザーが試しcmd --helpてからスクリプトを終了する必要があることをエコーアウトします。

問題は、無効なオプションが getopt によってキャッチされ、それ自体が「getopt: 無効なオプション -- 'x'」などのメッセージを出力しているということです。

getopt パラメータを設定するために使用しているパターンは次のとおりです。

set -- $(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@")

ここで、$LONG_OPTIONS と $SHORT_OPTIONS は両方とも、オプションのコンマ区切りリストです。

オプションの処理方法は次のとおりです。

 while [ $# -gt 0 ]
    do
        case "$1" in
            -h|--help)
                cat <<END_HELP_OUTPUT

    Help
    ----

    Usage: ./cmd.sh 

    END_HELP_OUTPUT

                shift;
                exit
                ;;
            --opt1)
                FLAG1=true
                shift
                ;;
            --opt2)
                FLAG2=true
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Option $1 is not a valid option."
                echo "Try './cmd.sh --help for more information."
                shift
                exit
                ;;
        esac
    done

getopt -qcase出力を抑制しますが、ステートメント内のトラップスキームはまだ期待どおりに機能しません。代わりに、無効な引数にもかかわらず、プログラムは実行されます。

4

6 に答える 6

14

この種のスタイルは私にとってうまくいきます:

params="$(getopt -o d:h -l diff:,help --name "$cmdname" -- "$@")"

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -d|--diff)
            diff_exec=(${2-})
            shift 2
            ;;
        -h|--help)
            usage
            exit
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done
于 2011-10-06T13:56:07.560 に答える
1

これが getopts ケース ステートメントの最後の項目として機能することがわかりました。

*) eval echo "認識できない引数 \$$[OPTIND-1]"; 利用方法; 出口 ;;

于 2013-07-19T14:22:22.427 に答える
1

これは最も堅牢なソリューションではありませんが、合理的です。以下に依存します。

  • 出力されるエラー メッセージにgetoptは、「getopt:」という接頭辞が付いています。
  • getoptカスタム情報で補強された、クリーンアップされたバージョンの のエラー メッセージを渡すことが許容されると想定されています。

コードスニペット:

# Invoke getopt; suppress its stderr initially.
args=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>/dev/null)
if [[ $? -ne 0 ]]; then # getopt reported failure
    # Rerun the same getopt command so we can capture stderr output *only* this time.
    # Inefficient (and a potential maintenance headache, if literals were involved), but this will only execute in case of invalid input.
    # Alternatively, redirect the first getopt invocation's stderr output to a temp. file and read it here.
    errmsg=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>&1 1>&-)
    # Strip getopt's prefix and augment with custom information.
    echo -e "${errmsg#getopt: }\nTry './cmd.sh --help for more information." 1>&2
    exit 1
fi
于 2012-06-06T19:53:57.360 に答える
1

getopt をまったく使用する必要がありますか? 使うだけなら

while [ $# -gt 0 ]; do
  case "$1" in
    -d|--diff)
       diff_exec=(${2-})
       shift
       ;;
    -h|--help)
       usage
       exit
       ;;
     --)
       break
       ;;
     *)
       usage
       ;;
    esac
    shift
done

次に、自分のコードがチェックを行っています。

于 2013-03-30T11:19:25.203 に答える
0

これは、私が使用したコマンドライン解析です。欠落しているオプションとパラメーターを処理するために、より多くの解析ロジックを使用して改善できます。

コマンド ラインの場合: -a AA -b BB -c CC、結果 s/ba=AA b=BB c=CC

OPT=( "$@" )  # Parses the command line into words.

for [[ I=0;I<${#OPT[@]};I++ ]]  
   do
      case "${OPT[$I]}" in         
         -a) a=${OPT[$I+1]} ;;         
         -b) b=${OPT[$I+1]} ;;         
         -c) c=${OPT[$I+1]} ;;    
      esac
  done
于 2013-11-02T02:27:24.787 に答える
0

これが役立つかどうかはわかりませんが、getopt(1)getopt(3)を使用し、正しく思い出せばgetopt(3)はOPTSTRINGの最初の文字がコロンの場合にエラー報告を抑制します。

于 2011-10-05T15:28:54.757 に答える