我正在尝试多次并行执行一个长时间运行的进程。每次执行该进程的参数都存储在一个空格分隔的环境变量中。下面是我尝试执行的一个虚构示例:
$ echo -e 1 2 3 4 | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
以下是该命令的输出:
1 2 3 4 is the number being processed
为什么 max-args 似乎被忽略了?然后我尝试明确设置分隔符,以获得更好的结果:
$ echo -e 1 2 3 4 | xargs -d " " --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
1 is the number being processed
2 is the number being processed
3 is the number being processed
4
is the number being processed
xargs 在处理第 4 个参数时在做什么?
经过一番搜索,我几乎得到了我想要的东西。参数处理正确,但并行性不起作用(使用此处未显示的另一个命令进行了验证):
$ echo -e 1 2 3 4 | xargs -n 1 | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
1 is the number being processed
2 is the number being processed
3 is the number being processed
4 is the number being processed
我错过了什么?
答案1
做
echo -e 1 2 3 4 | sed -e 's/\s\+/\n/g' | xargs --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
完成任务了吗?输出看起来差不多正确:
1 is the number being processed
2 is the number being processed
3 is the number being processed
4 is the number being processed
我还尝试用 替换echo
来sleep
确认它并行执行,并且确实执行了:
echo -e 1 2 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 | sed -e 's/\s\+/\n/g' | xargs --max-procs=20 --max-args=1 --replace=% sleep 1
答案2
据我所知,xargs 的默认输入分隔符是 \r ,因此您必须将其更改为 <space> 并相应地发送输入结尾,如下所示:
$ echo -n "1 2 3 4 " | xargs -d" " --max-procs=3 --max-args=1 --replace=% echo % is the number being processed
1 is the number being processed
2 is the number being processed
3 is the number being processed
4 is the number being processed
$
高血压
答案3
其他一些方法可能更简单,也可以使用-n
:-max-args
echo -n "foo bar baz" | tr ' ' '\n' | xargs -n 1 echo # With \n, no need for -0
echo -n "foo bar baz" | tr ' ' '\0' | xargs -0 -n 1 echo # Using null character
echo -n "foo bar baz" | xargs -d ' ' -n 1 echo # Telling to xargs the delimiter
- 当然,其中
echo
可以是任何您想要的命令。 - 另请参阅
-L
参数和-d '\n'
(如果行中有空格)。 - 流程与……并行
--max-procs
或可能更好parallel
。