这似乎是最安全的版本。
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
(-0 可以删除,tr 替换为重定向(或者文件可以替换为空分隔文件)。它主要在那里,因为我主要使用 xargs 和 find带有-print0 输出)(这也可能与没有-0 扩展的xargs 版本相关)
这是安全的,因为 args 在执行时会将参数作为数组传递给 shell。当使用["$@"][1]获得所有数据时,shell(至少bash)会将它们作为未更改的数组传递给其他进程
如果您使用...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' '',如果字符串包含双引号,则赋值将失败。对于使用-i 或-I 的每个变体都是如此。 (由于它被替换为字符串,您始终可以通过在输入数据中插入意外字符(如引号、反引号或美元符号)来注入命令)
如果命令一次只能接受一个参数:
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 "$@";' ''
这应该对输入中的任何特殊字符都具有鲁棒性。 (如果输入为空分隔符。)tr 版本如果某些行包含换行符,则会得到一些无效输入,但对于换行符分隔的文件,这是不可避免的。
bash -c 的空白第一个参数是由于:(来自bash man page)(感谢@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.