1

スクリプトで使用される引数の 2 倍を取得しています。

この次のコードを初めて使用して、不要な引数がないことを確認します (arg1:arg2:arg3 のみを考慮します)。

     PARAM=$@
     while [ "$#" -gt "0" ]; do
              case $1 in
                       arg1)
                                shift2
                                ;;
                       arg2)
                                shift
                                ;;
                       arg3)
                                shift
                                ;;
                       *)
                                echo "Usage : ./test.sh arg1 <VAL1> <VAL2> [arg2] [arg3]"
                                exit 2
                                ;;
              esac
              shift
     done

そして、これらの引数をもう一度解析し、arg1 を取得したときに次の 2 つの引数を取得できるようにしたいので、次のようなものから始めました。

     for command in $PARAM
     do
         case $command in
             arg1)
                 shift
                 VALUE1=$command
                 shift
                 VALUE2=$command
                 exec_arg1
                 ;;
         esac
         shift

しかし、「シフト」を使用しているときに、シフトエラーが発生します。多くシフトすることはできません

シバンは「#!/bin/sh」で、bash のシバン (つまり、「#!/bin/bash」) を使用せずに解決策を探しています。

4

1 に答える 1

2

リストを文字列に連結して安全にリストに戻すことはできません (複雑なヘルパー関数がなければ)。この FAQを参照してください。

shift異なるシェルでは異なる動作をします。Bash と Zsh では、位置パラメーターが残っていない場合は、shift単純に false を返します。Dash を含む多くのシェル (POSIX に反して、おそらく ksh の動作のため) は、代わりに致命的なエラーをスローします。ksh93 はビルトインを介してこれを回避する方法を提供しますcommandが、これも POSIX で指定されていないように見えますが、この回避策はとにかく Dash でも機能しますが、機能しませんmksh(昨日発見したばかりの mksh にもバグがあり、これが機能しません。メンテナはおそらく、回避策を可能にする方法でそれを修正しません)。Busybox も POSIX に従っておらず、意味のある終了コードを提供しません。

shiftとにかく、ポイントは、非常に多くのシェルにバグがあるため、信頼できないということです。可能であれば引数をシフトせずに反復し、残りの引数の数をテストして、現在行っているようにエッジを越えてシフトしていないことを確認する必要があります。引数を事前に検証するというあなたの考えは、検証と解析を同時に行うよりも優れているとは思いません。

#!/bin/sh

f()
    if ! ${_called_f+false}; then
        while ! ${1+false}; do
            case $1 in
                arg1)
                    ${3+:} return 1
                    value1=$2 value2=$3
                    shift 3
                    exec_arg1
                    ;;
                arg[23])
                    ${2+:} return 1
                    value1=$1
                    shift
                    "exec_arg${value1##"${value1%?}"}" # Only do this crap if restricted to POSIX
                    ;;
                *)
                    return 1
            esac
        done
    else
        # Hack nobody will understand since this probably isn't what you want anyway.
        _called_f= value1= value2= command eval \
            'typeset +x value{1,2} 2>/dev/null; f "$@"'
    fi

if ! f "$@"; then
    echo 'Error parsing args, exiting...' >&2
    exit 1
fi

参照:オプションの解析

于 2013-01-07T13:16:31.870 に答える