私はこのシナリオを持っています
first_arg="$1";
if foo; then
shift 1;
node foo.js "$@"
Elif bar; then
shift 1;
node bar.js "$@"
Elif baz; then
shift 1;
node baz.js "$@"
else
node default.js "$@"
fi
上記をこれに変えたい:
first_arg="$1";
shift 1;
if foo; then
node foo.js "$@"
Elif bar; then
node bar.js "$@"
Elif baz; then
node baz.js "$@"
else
unshift 1;
node default.js "$@"
fi
しかし、私がちょうど作ったシフトなしのようなオペレーターがいるかどうかはわかりません。回避策の1つは次のとおりです。
node default.js "$first_arg" "$@"
しかし、それを試したとき、私は奇妙な行動を得ました。
引数を配列に保存できます:
args=( "$@" ) # use double quotes
shift 1
if foo; then
node foo.js "$@"
Elif bar; then
node bar.js "$@"
Elif baz; then
node baz.js "$@"
else
node default.js "${args[@]}"
fi
そもそもshift 1
を使用する必要はありません。位置引数を使用し、それらのインデックスをスライスして引数を渡します。
first_arg="$1"
これを行うと、残りの引数は"${@:2}"
としてアクセスできます。表記は、位置引数2からリストの最後までを表す方法です。
あなたの例の構成を使用すると、
node foo.js "${@:2}"
そして最後のelse
部分は
node default.js "$1" "${@:2}"
これは、位置引数のシフトが行われないため、"$@"
を実行するのと同じです。
あなたが試したこと:
first_arg=$1
shift
# ...later...
else
node default.js "$first_arg" "$@"
fi
これは、少なくとも1つのコマンドライン引数がある場合、最初のバリアントと同じになります。
コマンドライン引数がない場合でも、"$first_arg"
は空の文字列、つまり引数になりますが、"$@"
は空の文字列も生成しません。
Nodeアプリケーションがコマンドラインで空の引数を受け入れる場合、2つのコードバリアントでアプリケーションの動作が異なる可能性があります。
コマンドライン引数なしでスクリプトを呼び出すことが有効な場合、次のようにすることができます
node default.js ${first_arg:+"$first_arg"} "$@"
ここで、${first_arg:+"$first_arg"}
は、first_arg
が空または未設定の場合は何にも展開されませんが、"$first_arg"
が空でない文字列に設定されている場合はfirst_arg
に展開されます。または、未設定または空の変数に対して明示的なエラーを発生させたい場合:
node default.js "${first_arg:?Error, no command line arguments}" "$@"
代替案には、$@
のコピーをbash
配列として作成することが含まれます Jesse_bが彼の回答で示しているように 。
$first_arg
を$@
に戻す
set -- "$first_arg" "$@"`
コマンドライン引数がない場合、これは$1
の$@
として空の引数を含むため、機能しません。
と
set -- ${first_arg:+"$first_arg"} "$@"`
$first_arg
が空の場合、または変数が存在しない場合は、何も「シフト解除」します。
シフトはシフト1と同じであり、単一のステートメントをで終了する必要がないことに注意してください。同じ行に別のステートメントが続いていない限り(newlineは;と同じようにコマンド終了文字です)。