这是我的脚本:
#! /bin/bash
ret=0
file_out1=$(mktemp)
file_out2=$(mktemp)
(echo first start; sleep 2s; echo first finish;) &> $file_out1 &
ret=$?
P1=$!
(echo second start; sleep 1s; echo second finish;) &> $file_out2 &
ret=$?
P2=$!
wait $P1 $P2 || ret=$?
cat $file_out1
cat $file_out2
exit $ret
在这里,输出是:
first start
first finish
second start
second finish
但输出应该是:
second start
second finish
first start
first finish
我的意思是,应该在完成cat $file_out1
后立即运行并且应该在完成后立即运行。P1
cat $file_out2
P2
而且,我要确保P1成功结束,P2成功结束。最后,我怎么知道P1
或P2
/或两者是否有错误。
在此脚本中,$ret
无法正常工作(它总是exit 0
)。在它工作之后,很高兴知道是$ret
来自P1
还是P2
。比如说P1
有返回码 x1,P2
有返回码 x2。如果存在非零退出代码,则使用非零返回代码退出程序。
更新1:
askubuntu 中的一个答案建议我们可以使用--group
并行命令的参数来确保每个命令的输出等到命令完成(避免混合输出)。
它显示的命令是parallel --group 'echo -n {};sleep {};echo {}' ::: 1 3 2 4
。
这个命令在我的机器上有效。但是,我不明白如何在我的上下文中使用此命令。
我的意思是我怎样才能得到
second start
second finish
first start
first finish
当输入命令echo first start; sleep 2s; echo first finish;
和echo second start; sleep 1s; echo second finish;
using gnu并行时。
更新 2:
我目前所在的代码是:
#! /bin/bash
function first {
echo first start
sleep 2s
echo first finish
}
function second {
echo second start
sleep 1s
echo second finish
}
export -f first && export -f second
parallel -j2 ::: first second
这实际上解决了我的问题。
我想你希望你的每个任务在它们终止时立即显示输出,但要避免折叠它们的输出,这就是为什么你将它缓冲在一个文件中 - 没关系,你也可以在输出前加上 sed,让它在它到来时流动,然后按需再次排序:那将是在数据量不可预测和存储溢出风险的情况下。
你的错误:
&
,您将无法访问它们的最终状态(您期望的ret=$?
是其他东西)wait
准时捕获每个进程的最终状态:进程终止后为时已晚,即使进程最终状态wait
是。这是不可预测的。127
0
您希望获得与顺序运行相同的反馈,但具有并行性的持续时间优势,并最大限度地减少酱料。
让他们在自己的盒子里执行,管理输出竞争——
flock
文件描述符是干净的——并强制他们在某处记录他们的最终状态——同样,文件描述符是干净的。正如@AhmadIsmail edit 所说, EDIT GNU parallel 是一体化解决方案。无论如何让这个。