将输出通过管道传输到另一个延迟命令时如何挂起主命令
How to suspend the main command when piping the output to another delay command
我有两个自定义脚本来实现它们自己的任务,一个用于输出一些 URLs(假装下面的 cat
命令),另一个用于接收 URL 来解析它通过网络请求(伪装成下面的 sleep
命令)。
这是原型:
案例一:
cat urls.txt | xargs -I{} sleep 1 && echo "END: {}"
输出是 END: {}
并且 sleep
有效。
案例二:
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:我有点疑惑,为什么会有这些输出?
问题 2:是否有任何解决方案可以为每个 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
在 BEGIN 和 END 之间脚本休眠一秒钟。
感谢shellter和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答案的启发,我发现我可以在xargs
中加入我对sh -c
的期望。
cat urls.txt | xargs -I{} -P 5 sh -c 'echo "BEGIN: {}" && sleep 1 && echo "END: {}"'
对于-P 5
,它使实用程序命令运行在并行模式下具有最大指定的子进程,以利用大部分带宽资源。
完成!
我有两个自定义脚本来实现它们自己的任务,一个用于输出一些 URLs(假装下面的 cat
命令),另一个用于接收 URL 来解析它通过网络请求(伪装成下面的 sleep
命令)。
这是原型:
案例一:
cat urls.txt | xargs -I{} sleep 1 && echo "END: {}"
输出是 END: {}
并且 sleep
有效。
案例二:
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:我有点疑惑,为什么会有这些输出?
问题 2:是否有任何解决方案可以为每个 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
在 BEGIN 和 END 之间脚本休眠一秒钟。
感谢shellter和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答案的启发,我发现我可以在xargs
中加入我对sh -c
的期望。
cat urls.txt | xargs -I{} -P 5 sh -c 'echo "BEGIN: {}" && sleep 1 && echo "END: {}"'
对于-P 5
,它使实用程序命令运行在并行模式下具有最大指定的子进程,以利用大部分带宽资源。
完成!