首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >获取后台进程的退出代码

获取后台进程的退出代码
EN

Stack Overflow用户
提问于 2009-10-15 04:24:04
回答 12查看 181.5K关注 0票数 162

我有一个从我的主bourne shell脚本调用的命令CMD,它永远需要花费很长时间。

我想修改脚本如下:

  1. 并行运行命令CMD作为后台进程(CMD &).
  2. In主脚本,每隔几秒就会有一个循环来监视衍生的命令。循环还向标准输出回显一些指示脚本进度的消息。当派生的命令terminates.
  3. Capture时,
  4. 退出循环,并报告派生的进程的退出代码。

有没有人能给我点建议来完成这个任务?

EN

回答 12

Stack Overflow用户

发布于 2009-10-15 05:01:23

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

4:wait <n>等待,直到PID为<n>的进程完成(它将阻塞,直到进程完成,所以您可能不想在确定进程完成之前调用它),然后返回已完成进程的退出代码。

2、3:psps | grep " $! "可以告诉你进程是否还在运行。这取决于你如何理解输出,并决定它离完成有多近。(ps | grep不是傻瓜式的。如果您有时间,您可以想出一种更健壮的方法来判断进程是否仍在运行)。

下面是一个框架脚本:

代码语言:javascript
复制
# 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
# The variable $? always holds the exit code of the last command to finish.
# Here it holds the exit code of $my_pid, since wait exits with that code. 
my_status=$?
echo The exit status of the process was $my_status
票数 157
EN

Stack Overflow用户

发布于 2015-04-09 17:53:23

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

代码语言:javascript
复制
# 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 finish, will take max 14s
# as it waits in order of launch, not order of finishing
for p in $pids; do
        if wait $p; then
                echo "Process $p success"
        else
                echo "Process $p fail"
        fi
done
票数 68
EN

Stack Overflow用户

发布于 2017-09-14 15:07:01

背景子进程的pid存储在$!中。您可以将所有子进程的pids存储到一个数组中,例如PIDS[]

代码语言:javascript
复制
wait [-n] [jobspec or pid …]

等待每个进程ID pid或作业规范jobspec指定的子进程退出,并返回等待的最后一个命令的退出状态。如果给定了作业规范,则等待作业中的所有进程。如果没有给定参数,则等待所有当前活动子进程,并且返回状态为零。如果提供了-n选项,wait将等待任何作业终止并返回其退出状态。如果jobspec和pid都没有指定shell的活动子进程,则返回状态为127。

使用 wait 命令可以等待所有子进程完成,同时可以通过$?获取每个子进程的退出状态,并将状态保存到STATUS[]中。然后,您可以根据状态执行某些操作。

我已经尝试了以下两种解决方案,它们运行良好。solution01更简洁,而solution02则有点复杂。

solution01

代码语言:javascript
复制
#!/bin/bash

# start 3 child processes concurrently, and store each pid into array PIDS[].
process=(a.sh b.sh c.sh)
for app in ${process[@]}; do
  ./${app} &
  PIDS+=($!)
done

# wait for all processes to finish, and store each process's exit code into array STATUS[].
for pid in ${PIDS[@]}; do
  echo "pid=${pid}"
  wait ${pid}
  STATUS+=($?)
done

# after all processed finish, check their exit codes in STATUS[].
i=0
for st in ${STATUS[@]}; do
  if [[ ${st} -ne 0 ]]; then
    echo "$i failed"
  else
    echo "$i finish"
  fi
  ((i+=1))
done

solution02

代码语言:javascript
复制
#!/bin/bash

# start 3 child processes concurrently, and store each pid into array PIDS[].
i=0
process=(a.sh b.sh c.sh)
for app in ${process[@]}; do
  ./${app} &
  pid=$!
  PIDS[$i]=${pid}
  ((i+=1))
done

# wait for all processes to finish, and store each process's exit code into array STATUS[].
i=0
for pid in ${PIDS[@]}; do
  echo "pid=${pid}"
  wait ${pid}
  STATUS[$i]=$?
  ((i+=1))
done

# after all processed finish, check their exit codes in STATUS[].
i=0
for st in ${STATUS[@]}; do
  if [[ ${st} -ne 0 ]]; then
    echo "$i failed"
  else
    echo "$i finish"
  fi
  ((i+=1))
done
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1570262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档