将输出传递给另一个延迟命令时,如何暂停主命令

时间:2019-07-04 03:33:45

标签: macos shell command-line xargs

我有两个自定义脚本来实现自己的任务,一个用于输出某些URL(在下面伪装为cat命令),另一个用于接收通过网络请求进行解析的URL(伪装为sleep命令)。

这是原型:

情况1:

cat urls.txt | xargs -I{} sleep 1 && echo "END: {}"

输出为END: {}sleep有效。

情况2:

cat urls.txt | xargs -I{} echo "BEGIN: {}" && sleep 1 && echo "END: {}"

输出为

BEGIN: https://www.example.com/1
BEGIN: https://www.example.com/2
BEGIN: https://www.example.com/3
END: {}

但似乎只有sleep 1秒。

Q1:我有些困惑,为什么会有这些输出?

Q2:是否有解决方案为每个xargs行输出执行完整的流水线cat延迟命令?

2 个答案:

答案 0 :(得分:2)

您可以将命令放在单独的脚本中:

worker.sh

#!/bin/bash
echo "BEGIN: $*" && sleep 1 && echo "END: $*"

设置执行权限:

chmod +x worker.sh

并使用xargs调用它:

cat urls.txt | xargs -I{} ./worker.sh {}

输出

BEGIN: https://www.example.com/1
END: https://www.example.com/1
BEGIN: https://www.example.com/2
END: https://www.example.com/2
BEGIN: https://www.example.com/3
END: https://www.example.com/3

BEGIN和END之间的脚本休眠一秒钟。

答案 1 :(得分:1)

感谢脱壳机和UtLox的提醒,我发现xargs是关键。

这是我的发现,shell / zsh解释器将sleep 5echo END: {}拆分为另一个命令序列,因此xargs没有收到我期望的两个&&内联命令作为一种实用程序命令,并将{}替换为END表达式中的值。 xargs -t可以证明这一点。

cat urls.txt | xargs -I{} -t echo "BEGIN: {}" && sleep 1 && echo "END: {}"

受UtLox答案的启发,我发现我可以和sh -c中的xargs一起加入我的期望。

cat urls.txt | xargs -I{} -P 5 sh -c 'echo "BEGIN: {}" && sleep 1 && echo "END: {}"'

对于-P 5,它使实用程序commmand在并行模式下与最大指定子进程一起运行,以利用大多数带宽资源。

完成!