【问题标题】:Bash wait for several simultaneous subprocesses and kill all on errorBash 等待几个同时发生的子进程并在错误时杀死所有子进程
【发布时间】:2016-11-20 02:28:52
【问题描述】:

我正在运行一个带有多个同时命令的 bash 脚本(python 脚本)。 如果其中一个进程失败,我正在尝试杀死所有进程。 问题是 python 脚本仍在后台运行,如果其中一个失败,我的 bash 脚本不知道。

这是我脚本中的一个 sn-p:

set -a
trap cleanup_children SIGTERM
MY_PID=$$

function thread_listener () {
    to_execute="$1"
    echo "Executing $to_execute ..."
    $to_execute &
    PID=$!
    trap 'echo killing $PID; kill $PID' SIGTERM
    echo "Waiting for $PID ($to_execute) ..."
    wait $PID || if `kill -0 $MY_PID &> /dev/null`; then kill $MY_PID; fi
}

function cleanup_children () {
    for job in `jobs -p`
    do
        if `kill -0 $job &> /dev/null`; then
            echo "Killing child number $job"
            ps -p $job
            kill $job
        fi
    done
}

function create_app1 () {
    cd ${GIT_DIR}
    python ./create-app.py -myapp
    exit_code=$?
    echo "Create app1 ISO result: ${exit_code}"
    [ "${exit_code}" == "1" ] && exit 1
    mv ${ISO_OUTPUT_DIR}/rhel-7.1.iso ${ISO_OUTPUT_DIR}/${ISO_NAME}.iso
}

function create_app2 () {
    cd ${GIT_DIR}
    python ./create-app.py -do-something
    exit_code=$?
    echo "Create app1 ISO result: ${exit_code}"
    [ "${exit_code}" == "1" ] && exit 1
    mv ${ISO_OUTPUT_DIR}/rhel-7.1.iso ${ISO_OUTPUT_DIR}/${ISO_NAME}.iso
}

export -f create_app1
export -f create_app2

echo "MY_PID=$MY_PID"
thread_listener create_app1 &
PID_APP1=$!

thread_listener create_app2 &
PID_APP2=$!
wait

kill $PID_APP1 2> /dev/null
kill $PID_APP2 2> /dev/null

【问题讨论】:

    标签: linux bash signals wait sigterm


    【解决方案1】:

    嗯,这看起来很高级;)。我是否正确地假设您永远不会看到“创建 app1 ISO 结果”输出,因为 python 脚本没有终止?信号未正确分派到 bash 后台作业可能是个问题。它也可能与您的 python 代码对信号没有正确反应有关。你签出https://docs.python.org/2/library/signal.html了吗?当然,您必须弄清楚如何在执行时中断 python 代码的确切步骤。我建议首先确保 python 代码以你想要的方式对信号做出反应。

    【讨论】:

    • 实际上我正在从我的 Python 脚本中获取退出代码,但是当我实际使用 1 退出时,它不会将 TERM 信号发送到父脚本(作业)或至少它不会终止仍在运行的其他 Python 脚本
    • 如果您发布完整运行的输出并指出失败的行,也许可以对此有所了解。我认为必须逐步了解确切的时间来解决这个问题。
    • 你将如何实现 bash 脚本来实现我的目标(这只是一个包装脚本)并且我确实从 Python 脚本中获取了退出代码,所以很明显问题不存在,可能有与捕获并转发到父/子进程的错误信号有关
    • 必须是 bash 吗?否则我可能会在 python 中重写包装器本身。
    • 那么你想要达到的效果是这样的:并行运行两个作业。如果其中一个失败,则终止另一个。否则让作业运行直到完成。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2010-12-08
    相关资源
    最近更新 更多