获取后台进程的退出代码

我有一个从我的主Bourne shell脚本中调用的命令CMD,这个脚本需要永久使用。

我想修改脚本,如下所示:

  • 并行运行命令CMD作为后台进程($ CMD&)。
  • 在主脚本中,每隔几秒就有一个循环来监视生成的命令。 该循环还将一些消息回显给stdout,指示脚本的进度。
  • 生成的命令终止时退出循环。
  • 捕获并报告产生的进程的退出代码。
  • 有人可以给我指针来完成这个吗?


    1:在bash中, $! 保存最后执行的后台进程的PID。 无论如何,这将告诉你要监控的过程。

    4: wait <n>等待,直到具有ID的进程完成(它将阻塞,直到进程完成,因此您可能不想调用此方法直到确定进程已完成)。 wait返回后,进程的退出代码返回到变量$?

    2,3: psps | grep " $! " ps | grep " $! "可以告诉你进程是否仍在运行。 这取决于你如何理解输出并决定完成的程度。 ( ps | grep不是傻瓜式的,如果有时间,你可以想出一个更强大的方式来判断这个过程是否仍在运行)。

    这是一个框架脚本:

    # simulate a long process that will have an identifiable exit code
    (sleep 15 ; /bin/false) &
    my_pid=$!
    
    while   ps | grep " $my_pid "     # might also need  | grep -v grep  here
    do
        echo $my_pid is still in the ps output. Must still be running.
        sleep 3
    done
    
    echo Oh, it looks like the process is done.
    wait $my_pid
    my_status=$?
    echo The exit status of the process was $my_status
    

    当我有类似的需求时,我就是这样解决它的:

    # Some function that takes a long time to process
    longprocess() {
            # Sleep up to 14 seconds
            sleep $((RANDOM % 15))
            # Randomly exit with 0 or 1
            exit $((RANDOM % 2))
    }
    
    pids=""
    # Run five concurrent processes
    for i in {1..5}; do
            ( longprocess ) &
            # store PID of process
            pids+=" $!"
    done
    
    # Wait for all processes to finnish, will take max 14s
    for p in $pids; do
            if wait $p; then
                    echo "Process $p success"
            else
                    echo "Process $p fail"
            fi
    done
    

    正如我所看到的几乎所有答案都使用外部实用程序(主要是ps )来轮询后台进程的状态。 还有一个更加unixesh的解决方案,捕获SIGCHLD信号。 在信号处理程序中,必须检查哪个子进程已停止。 它可以通过kill -0 <PID>内置(通用)或检查/proc/<PID>目录(Linux特定)或使用内置jobs (bash specific。jobs jobs -l还报告在这种情况下,输出的第三个字段可以是Stopped | Running | Done | Exit。)。

    这是我的例子。

    启动的过程称为loop.sh 它接受-x或一个数字作为参数。 对于-x退出并退出代码1.对于一个数字,它会等待num * 5秒。 每5秒钟打印一次PID。

    启动程序进程名为launch.sh

    #!/bin/bash
    
    handle_chld() {
        local tmp=()
        for((i=0;i<${#pids[@]};++i)); do
            if [ ! -d /proc/${pids[i]} ]; then
                wait ${pids[i]}
                echo "Stopped ${pids[i]}; exit code: $?"
            else tmp+=(${pids[i]})
            fi
        done
        pids=(${tmp[@]})
    }
    
    set -o monitor
    trap "handle_chld" CHLD
    
    # Start background processes
    ./loop.sh 3 &
    pids+=($!)
    ./loop.sh 2 &
    pids+=($!)
    ./loop.sh -x &
    pids+=($!)
    
    # Wait until all background processes are stopped
    while [ ${#pids[@]} -gt 0 ]; do echo "WAITING FOR: ${pids[@]}"; sleep 2; done
    echo STOPPED
    

    有关更多解释,请参阅:从bash脚本启动进程失败

    链接地址: http://www.djcxy.com/p/97127.html

    上一篇: Get exit code of a background process

    下一篇: check if file exists on remote host with ssh