如何在Bash脚本中等待子过程,如果其中一个失败了,请停止所有人
如何在Bash脚本中等待子过程,以及其中一个是否返回出口代码1,因此我想停止所有子过程。
这就是我试图做的。 但是存在一些问题:
如果第一个过程比所有其他过程都长,而另一个过程在后台失败...那么脚本等待第一个过程完成,即使另一个过程已经失败了。
无法检测到该滴定失败,因为我将管道用于所需的打印格式。
#!/bin/bash
function doSomething()
{
echo [ $1 start ]
sleep $1
if [ $1 == 10 ]; then
failed
fi
echo [ sleep $1 ]: done
}
function failed(){
sleep 2
echo ------ process failed ------
exit 1
}
function process_log() {
local NAME=$1
while read Line; do
echo [Name ${NAME}]: ${Line}
done
}
pids=""
(doSomething 4 | process_log 4)&
pids+="$! "
(doSomething 17 | process_log 17)&
pids+="$! "
(doSomething 6 | process_log 6)&
pids+="$! "
(doSomething 10 | process_log 10)&
pids+="$! "
(doSomething 22 | process_log 22)&
pids+="$! "
(doSomething 5 | process_log 5)&
pids+="$! "
for pid in $pids; do
wait $pid || (pkill -P $$ ; break)
done
echo done program
有人有主意吗?
How to wait in bash script to subprocess and if one of them return exit code 1 so I want to stop all subprocess.
This is what I tried to do.
But there are a some of issues:
If the first process is longer than all the others, and another process fails in the background ... then the script waits for the first process to finish, even though another process has already failed.
Can't detect that doSomething failed because I use pipe for the desired print format.
#!/bin/bash
function doSomething()
{
echo [ $1 start ]
sleep $1
if [ $1 == 10 ]; then
failed
fi
echo [ sleep $1 ]: done
}
function failed(){
sleep 2
echo ------ process failed ------
exit 1
}
function process_log() {
local NAME=$1
while read Line; do
echo [Name ${NAME}]: ${Line}
done
}
pids=""
(doSomething 4 | process_log 4)&
pids+="$! "
(doSomething 17 | process_log 17)&
pids+="$! "
(doSomething 6 | process_log 6)&
pids+="$! "
(doSomething 10 | process_log 10)&
pids+="$! "
(doSomething 22 | process_log 22)&
pids+="$! "
(doSomething 5 | process_log 5)&
pids+="$! "
for pid in $pids; do
wait $pid || (pkill -P $ ; break)
done
echo done program
Anyone have an idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它的要旨是:
解释的
想法是使子过程在失败时通知父脚本(使用
sigusr1
信号);然后,主要脚本将在收到该信号时杀死所有子处理。但是有一个问题:杀死子过程的PID可能还不够,例如,当它当前正在运行
|
的命令时。在那些情况下,您需要杀死整个进程组,可以通过使用作业控制使用set -m
来完成,并使用负面kill
命令中的pid。The gist of it would be:
Explanations
The idea is to make the sub-processes notify the parent script when they fail (with a
SIGUSR1
signal); the main script will then kill all the sub-processes when it receives that signal.There's a problem though: killing the PID of a sub-process might not be enough, for example when it is currently running a command with a
|
. In those cases you need to kill the whole process group, which can be done by enabling job control withset -m
and by using a negative PID in thekill
command.gnu并行
- 现在停止读取,1 -tag
对于该特定
process_log
pregence of to to to to in Line行的参数,GNU Parallel可以用一个衬里做。安装:
测试:
输出:
我们看到
4
和5
从未完成,因为3
在它们之前失败了。并且每行都由其输入参数前缀。GNU平行还可以涵盖其他一些常见的前缀用例:
我的额外评论https://stackoverflow.com/questions/71776455/71776455/stop-bash-if-rany-oy-----------------------------------------------------74817154#74817154"> stop bash,如果任何功能都在并行也在这里申请。
在Ubuntu 22.04上进行了测试。
GNU parallel
--halt-on-error now,1 --tag
For that specific
process_log
that prepends arguments to each line, GNU parallel can do it with a one liner.Install:
Test:
Output:
So we see that
4
and5
never finished because3
failed before them. And each line is prefixed by its input arguments.GNU parallel can also cover some other common prefixing use cases:
My extra remarks from: Stop bash if any of the functions fail in parallel also apply here.
Tested on Ubuntu 22.04.