并行运行多个命令并干净利落地退出

时间:2017-12-07 19:18:18

标签: bash shell parallel-processing

在这个例子中,我有三个并行运行的命令。

sleep 1 && echo 'one' &
sleep 2 && echo 'two'&
sleep 1 && echo 'three'&
sleep 2 && echo 'four' & 
wait

echo "done"

当我使用键盘快捷键退出/退出命令时,命令似乎仍在输出。

➜  example: ✗ sh ./scripts.sh
three
one
two
four
done
➜  example: ✗ sh ./scripts.sh
^C%➜  example: ✗ one
three
two
four

如何彻底退出?

2 个答案:

答案 0 :(得分:1)

默认情况下由Kernal处理的信号,但我已经看到参考说明除了kill之外的所有信号也可以由程序处理,我们可以使用如下所示的陷阱捕获CNTRL + C信号,

finish(){
    < code to kill child process goes here >
}
trap finish EXIT

sleep 1 && echo 'one' &
sleep 2 && echo 'two' &
sleep 1 && echo 'three'&
sleep 2 && echo 'four' &

wait

了解更多信息,stackoverflowredsymbol.net

答案 1 :(得分:0)

借助@ JithinScarla的帮助和其他stackoverflow post I made我把它放在一起似乎完成了工作。

process_ids=( )

finish(){
    for i in "${process_ids[@]}"; do
        kill -9 $i > /dev/null 2> /dev/null || :
    done
}

append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax

{ sleep 1 && echo 'one'; } & append $!
{ sleep 5 && echo 'two'; } & append $!
{ sleep 1 && echo 'three'; } & append $!
{ sleep 5 && echo 'four'; } & append $!

echo "Background processes:"              # Demonstrate that our array was populated
printf ' - %s\n' "${process_ids[@]}"

trap finish EXIT

wait

或者甚至更清洁:

function runParallel {
    process_ids=( )
    finish(){
        for i in "${process_ids[@]}"; do
            kill -9 $i > /dev/null 2> /dev/null || :
        done
    }
    append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax
    processes=( "$@" )
    for i in "${processes[@]}"; do
        { eval $i; } & append $!
    done
    trap finish EXIT
    wait
}

runParallel \
    "sleep 1 && echo 'one'" \
    "sleep 5 && echo 'two'" \
    "sleep 1 && echo 'three'" \
    "sleep 5 && echo 'four'"