これが最も安全なバージョンのようです。
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;' ''
拡張機能を備えたGNUxargs
または別の-P
プロセスがあり、32個のプロセスを並行して実行したい場合、各プロセスには、コマンドごとに10個以下のパラメーターがあります。
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
これは、入力内の特殊文字に対して堅牢である必要があります。(入力がnullで区切られている場合。)tr
一部の行に改行が含まれている場合、バージョンは無効な入力を取得しますが、改行で区切られたファイルでは避けられません。
の空白の最初のパラメータbash -c
はこれによるものです:(bash
マニュアルページから)(ありがとう@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.