それを達成するための本当に優れた方法はありません。回避策しかありません。ほとんどすべての一般的な解決策では、個々の引数を個々の引数として渡す必要があります。これは、引数のリストを単一の引数として渡すという代替案では、少し複雑な引数 (あなたの例は、あなたが陥ろうとしているメタクォートの泥沼の始まりにすぎません. 詳細については、この Bash FAQ エントリを参照してください)。
おそらく最も一般的な解決策は、パススルーする引数を引数リストの最後に置くことです。これは、実際にスクリプト用の引数の末尾を知る必要があることを意味します。これは多かれ少なかれ、固定数の位置パラメーターがあることを意味します。通常、固定数は 1 です。この戦略の例は、スクリプトの名前を 1 つの位置引数として受け取るスクリプト インタープリター (bash
それ自体、など) です。python
それはあなたの呼び出しになります:
./script baz -a -b "foo bar"
それは必ずしも便利ではありません。find
たとえば、コマンドにはオプション-exec
があり、その後に続く引数で実際のコマンドが続きます。そのためには、通過する単語がどこで終わるかを知る必要があります。find
特定の区切り文字引数、つまり単一のセミコロンを使用して解決します。(これは任意の選択でしたが、スクリプトの引数としては非常にまれであるため、通常はうまくいきます。) その場合、呼び出しは次のようになります。
./script -f -a -b "foo bar" \; baz
明らかに、引用符で囲む;
必要があります。そうしないと、コマンドが終了してしまうからです。しかし、それは複雑な引用符の問題ではありません。
これは、ユーザーが区切り文字を明示的に指定できるようにすることで拡張できます。
./script --arguments=--end -a -b "foo bar" --end baz
find
-like 提案のサンプル コードを次に示します。
# Use an array to accumulate the arguments to be passed through
declare -a passthrough=()
while getopts f:xyz opt; do
case "$opt" in
f)
passthrough+=("$OPTARG")
while [[ ${!OPTIND} != ';' ]]; do
if ((OPTIND > $#)); then
echo "Unterminated -f argument" >>/dev/stderr
exit 1
fi
passthrough+=("${!OPTIND}")
((++OPTIND))
done
((++OPTIND))
;;
# Handle other options
esac
done
# Handle positional arguments
# Use the passthrough arguments
grep "${passthrough[@]}" # Other grep arguments