并行运行多个命令,并在其中一个命令失败或所有命令都成功时返回

时间:2015-08-27 12:00:14

标签: bash parallel-processing

我见过以下问题:Bash run two commands and get output from both几乎满足了我的需要。

但是,wait命令是阻塞的,这意味着如果命令2在命令1成功之前失败,则命令2失败时命令不会返回,但只有当命令1成功时才会返回。

是否可以并行运行多个命令,并且只要其中一个命令失败就返回1,如果所有命令都成功则返回0(并尽快返回)?

如果使用标准命令(如xargs或parallel)可能会更好,但如果使用bash编写它也可以。

2 个答案:

答案 0 :(得分:2)

此代码提供正确的退出代码,并杀死幸存者进程:

#/bin/bash

# trap for SIGTERM and set RET_VALUE to false
trap "RET_VAL=false" SIGTERM

MY_PID=$$
# Initialize RET_VALUE to true
RET_VAL=true

# This function will executed be in a separate job (see below)
thread_listener() {
    # Starts the long time job 
    ./longJob.sh &
    PID=$!
    # trap for sigterm and kill the long time process
    trap "kill $PID" SIGTERM
    echo waiting for $PID
    echo Parent $MY_PID
    # Send a SIGTERM to parent job in case of failure
    wait $PID || kill $MY_PID
    exit
}

echo $MY_PID

# Runs thread listener in a separate job
thread_listener &
PID1=$!

# Runs thread listener in a separate job
thread_listener &
PID2=$!

wait
# send sigterm to PID1 and PID2 if present
kill $PID1 2> /dev/null
kill $PID2 2> /dev/null
# returns RET_VALUE
$RET_VAL

有关代码的说明,请参阅注释。 诀窍是如果需要,启动能够接受或发送信号给父工作的工作。

子作业在其长时间工作失败的情况下向父母发送信号,并且父母在等待之后向其子女发送信号(父母接收到等待立即返回的信号)

答案 1 :(得分:0)

最近版本的GNU Parallel专注于这个问题。杀死正在运行的孩子,如果一个孩子失败了:

parallel --halt now,fail=1 'echo {};{}' ::: true false true true false

杀死正在运行的孩子,如果一个人成功:

parallel --halt now,success=1 'echo {};{}' ::: true false true true false

如果20%失败,请杀死正在跑步的孩子:

parallel -j1 --halt now,fail=20% 'echo {#} {};{}' ::: true true true false true true false true false true

在每个信号之间等待50毫秒的同时,给孩子发出TERM,TERM,TERM,KILL信号:

parallel --termseq TERM,50,TERM,50,TERM,50,KILL -u --halt now,fail=1 'trap "echo TERM" SIGTERM; sleep 1;echo {};{}' ::: true false true true false