我有两个自定义脚本来实现自己的任务,一个用于输出某些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:是否有任何解决方案可以执行每个cat
线输出的完整管道xargs
延迟命令?
您可以将命令放入单独的脚本中:
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
在开始和结束脚本之间睡一秒钟。
感谢您的助攻和utlox的提醒,我发现xargs
是关键。
这是我的发现,Shell/ZSH解释器将sleep 5
和echo END: {}
分为另一个命令,因此xargs
没有收到我的预期两个&&
Inline命令作为一个效用命令,并用END
表达式中的值替换为{}
。这可以通过xargs -t
。
cat urls.txt | xargs -I{} -t echo "BEGIN: {}" && sleep 1 && echo "END: {}"
受UTLOX的答案的启发,我发现我可以在xargs
中加入sh -c
的期望。
cat urls.txt | xargs -I{} -P 5 sh -c 'echo "BEGIN: {}" && sleep 1 && echo "END: {}"'
对于-P 5
,它使实用程序Commmand在并行模式下使用最大指定子过程运行,以利用大多数带整个范围的资源。
完成!