私はそれらの引数を引用符で生成できるスクリプトを書きました
シェルに対して出力が適切に引用されていて、その出力を信頼できる場合は、その出力で実行できますeval
。
配列をサポートするシェルがあると仮定すると、取得した引数を格納するためにそれを使用するのが最善です。
の./gen_args.sh
ような出力が生成された場合は'foo bar' '*' asdf
、実行して結果をeval "args=( $(./gen_args.sh) )"
呼び出す配列を生成できargs
ます。それは三つの要素だろうfoo bar
、*
、asdf
。
我々は使用することができ"${args[@]}"
、個々の配列要素を展開していつものように:
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(引用符に注意してください。"${array[@]}"
変更されていない個別の引数としてすべての要素に展開されます。引用符がないと、配列要素は単語分割の対象になります。たとえば、BashGuideの配列ページを参照してください。)
ただし、eval
はシェルの置換を問題なく実行するため$HOME
、出力ではホームディレクトリに展開され、コマンド置換は実際に実行中のシェルでコマンドを実行しeval
ます。の出力は"$(date >&2)"
、単一の空の配列要素を作成し、現在の日付を標準出力に出力します。これはgen_args.sh
、ネットワーク上の別のホスト、他のユーザーが作成したファイル名など、信頼できないソースからデータを取得する場合の懸念事項です。出力には任意のコマンドが含まれる可能性があります。(それget_args.sh
自体が悪意のあるものである場合、何も出力する必要はなく、悪意のあるコマンドを直接実行できます。)
evalなしでは解析が困難なシェルクォートの代わりに、スクリプトの出力でセパレータとして他の文字を使用することもできます。実際の引数では不要なものを選択する必要があります。
を選択#
して、スクリプトを出力しますfoo bar#*#asdf
。これで、引用符なしのコマンド展開を使用して、コマンドの出力を引数に分割できます。
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
IFS
スクリプト内の他の場所で単語の分割に依存している場合は後で設定し直す必要があり(unset IFS
デフォルトにするために機能するはずです)、set +f
後でグロビングを使用する場合にも使用する必要があります。
Bashや配列を持つ他のシェルを使用していない場合は、そのために位置パラメーターを使用できます。に置き換えargs=( $(...) )
てset -- $(./gen_args.sh)
、"$@"
代わりに使用してください"${args[@]}"
。(ここでも、を引用符で囲む必要があります"$@"
。そうしないと、位置パラメータは単語分割の対象になります。)
eval
使用できますが、通常はお勧めしません。xargs
も考慮する必要があります