getoptsを使用して挿入された値を操作する方法

getoptsを使用して挿入された値を操作する方法

私はこのbashコードをgetoptsと組み合わせて、getoptsを正しく理解したら、OPTINDには次のコマンドラインオプションのインデックスが含まれています。その場合は、私の言葉を訂正してください。私は間違っていますが、基本的に関数のローカル変数と同じ概念です。

それで、これによると、オプションが私に何の結果も与えない[-a somevalue ]のはなぜですか?[-b somevalue ]私は何が間違っていましたか?

OPT_A=A
OPT_B=B

while getopts :a:b FLAG; do
 case $FLAG in
    a) 
      OPT_A=$OPTARG
      ;;
    b) 
     OPT_B=$OPTARG
      ;;
  esac
done

shift $((OPTIND-1))

    while [ $# -ne 0 ]; do

if [[ -z $OPT_A ]]; then
    if [ `echo $1 | grep -o '\.' | wc -l` -ne 3 ]; then
        echo "Parameter '$1' does not look like an IP Address (does not contain 3 dots).";
            exit 1;
        elif [ `echo $1 | tr '.' ' ' | wc -w` -ne 4 ]; then
            echo "Parameter '$1' does not look like an IP Address (does not contain 4 octets).";
        exit 1;
            else
        for OCTET in `echo $1 | tr '.' ' '`; do
                if ! [[ $OCTET =~ ^[0-9]+$ ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' is not numeric).";
                        exit 1;
                elif [[ $OCTET -lt 0 || $OCTET -gt 255 ]]; then
                        echo "Parameter '$1' does not look like in IP Address (octet '$OCTET' in not in range 0-255).";
                        exit 1;
                fi
        done
    fi
fi


if [[ -z $OPT_B ]]; then
        if [[ "$2" =~ ^[0-9]+$ ]] && [ "$2" -ge 1 -a "$2" -le 10000 ]; then 
            echo "chosen variable: $2";
            exit 1;
            else echo "variable $2 is not in range '1 - 10000'";
            exit 1;
        fi
    fi

    done
    exit 0

ベストアンサー1

これは、すべてのロジックがそのうちの1つが空でなければ$OPT_[AB]ならないためです。ただし、パラメータを渡さなくても引き続き-[ab] $OPTARG使用できますOPT_[AB]=[AB]。したがって、論理チェーンはルートを通過しません。

if [[ -z $OPT_A ]]; then...

...声明。

まあ..いいえみんなあなたの論理はこれに依存します。また、次のことをしています。

shift $((OPTIND-1))

    while [ $# -ne 0 ]...

したがって、通過すると3に設定されscript -a argます。だからあなたはgetopts$OPT_Aarg$OPTINDshift 2 (すべての投稿)これによりテストはすぐに失敗しますwhile。したがって、をcase設定すると、$OPT_A次に何が起こるかですexit 0。だから$OPT_A利用可能であることを確認していないようです。

それにもかかわらず、ほとんどのロジックはテスト失敗のために設計されているため、重要ではありません。しかし、スクリプトはただ exitS. varを作成しました$OPT_Aが、何もしません。スクリプトの後、この値は使用できませんexit。あらかじめ設定されたIPCはありませんが、ここにはそのようなものはありません。スクリプトはサブシェルから呼び出され、親シェルに戻ると設定した値は失われます。

さらに重要なのは:a:boptstring$OPTARGです-b。 optstring の先行コロンは自動操作を示します。stderrオプションまたはその引数に問題がある場合は記録されません。しかし、コロン続くオプション文字は、オプションに引数が必要であることを示します。良い:

while getopts :a:b: FLAG

...引数が必要な2つのオプションを表します。しかし、これは難しいかもしれません。引数を受け入れる必要があるとマークした後、getopts引数がないことが確認された場合はエラーとして表示されるためです。

sh -c 'getopts :a:b: opt -a; echo "$opt $OPTARG"'

...印刷...

: a

この場合、オプションは最終的になります$OPTARG。私たちがそれについてあまり沈黙していなければ、それはより明確になります。:$opt:

sh -c 'getopts a:b: opt -a; echo "$opt $OPTARG"'
No arg for -a option

:したがって、コロンを確認する必要があります。?これは通常、単純な内容を印刷するためにパスをリセットする別の種類のエラーです--help

$OPT_[AB]個人的には、最初からそれらがすべて空であることを確認し、いくつかのロジックを実行して正しく設定し、テストループを完了して最後のテストを空にするように設定します。それらがまったく価値がない場合、それは私が扱わない何らかの理由であるに違いありません、とにかくバグです。これがテストループを実行する方法の始まりです...

param_err(){
    set '' "$@"
    : "${1:?Parameter '$OPTARG' does not look like an IP Address $2}"
}

test_oct(){ 
    oIFS=$IFS; unset "${IFS+o}oIFS"; IFS=.
    for oct in $1; do  [ $oct -lt 256 ] || 
        param_err "('$oct' too large)"
    done; unset IFS oct
    : "${oIFS+${IFS=$oIFS}}"
}

a_param()
    case ${1##*.*.*.*.*} in (a) OPT_A=A;;  #some default - no arg provided                                            
          (.*|*..*|*.) param_err '(empty octet)';;
          (*[!.0-9]*)  param_err '(octet is not positive integer)';;
          (*.*.*.*)    test_oct  "$1"; OPT_A=$1;;
          (*?*)        param_err '(too few octets)';;
          (*)          param_err ${1:+"(too many octets)"} '(null param)';;
    esac

unset OPT_A OPT_B
while getopts :a:b:c:d: opt
do    case ${opt#:}$OPTARG in
      a*)   a_param "$OPTARG";;
      b*)   b_param "$OPTARG";; #tests as needed similar to a_param()
      ?*)   help;;              #param_err should call this too, but it just exits
      esac
done                

おすすめ記事