我有两个自定义脚本来实现自己的任务,一个用于输出某些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
延迟命令?
答案 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 5
和echo 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在并行模式下与最大指定子进程一起运行,以利用大多数带宽资源。
完成!