これが最も安全なバージョンのようです。
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
(-0
除去することができ、tr
リダイレクト(またはファイルと置き換えがNULLに置き換えることができる)の代わりにファイルを分離した。私が主に使用するので、それはそこに主にあるxargs
とfind
して-print0
出力)(これも上の関連するかもしれないxargs
無しバージョン-0
拡張)
argsは実行時にパラメータを配列としてシェルに渡すため、安全です。シェル(少なくともbash
)は、すべてを使用して取得したときに、変更されていない配列として他のプロセスに渡します["$@"][1]
を使用...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
する場合、文字列に二重引用符が含まれていると割り当てが失敗します。これは、-i
またはを使用するすべてのバリアントに当てはまります-I
。(文字列に置き換えられるため、予期しない文字(引用符、バッククォート、ドル記号など)を入力データに挿入することで、いつでもコマンドを挿入できます)
コマンドが一度に1つのパラメーターしか取らない場合:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
またはやや少ないプロセスで:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
GNU xargs
またはその他の-P
拡張機能があり、32のプロセスを並行して実行する場合、各プロセスのパラメーターはそれぞれ10以下です。
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
これは、入力の特殊文字に対して堅牢でなければなりません。(入力がnullで区切られている場合。)tr
改行が含まれている行がある場合、バージョンは無効な入力を取得しますが、改行で区切られたファイルではそれが避けられません。
の空白の最初のパラメーターbash -c
はこれが原因です:(bash
manページから)(ありがとう@clacke)
-c If the -c option is present, then commands are read from the first non-option argument com‐
mand_string. If there are arguments after the command_string, the first argument is assigned to $0
and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets
the name of the shell, which is used in warning and error messages.