返回后台进程的值

时间:2011-07-18 16:25:06

标签: unix shell background return-value

我需要根据后台进程的返回值采取一些操作,即它是否首先终止。

具体来说:在理想的操作中,我作为后台进程运行的服务器将永远运行。在这种情况下保持它在后台是有道理的,因为我希望我的shell脚本在产生服务器后做其他事情。但是如果服务器异常终止,我想最好使用服务器的退出返回值来决定是否杀死我的主脚本。如果那是不可能的,我至少想要中止主脚本,而不是用失败的服务器运行它。

我正在寻找一些针对shell脚本的异步回调的东西。一种解决方案是生成一个监视进程,定期检查服务器是否发生故障。我希望在主shell脚本本身内没有这样做。

3 个答案:

答案 0 :(得分:2)

当子进程通过捕获SIGCHLD时,您可以使用shell陷阱来调用函数。如果只有一个后台进程在运行,那么您可以在sigchld处理程序中wait获取它并获取其状态。如果有多个背景孩子在运行它会变得更复杂一些;这是一个代码示例(仅使用bash测试):

set -m # enable job control
prtchld() {  
  joblist=$(jobs -l | tr "\n" "^")
  while read -a jl -d "^"; do
    if [ ${jl[2]} == "Exit" ] ; then 
      job=${jl[1]} 
      status=${jl[3]}  
      task=${jl[*]:4}
      break  
    fi  
  done <<< $joblist
  wait $job 
  echo job $task exited: $status
}
trap prtchld SIGCHLD

(sleep 5 ; exit 5) &
(sleep 1 ; exit 7) &

echo stuff is running

wait

答案 1 :(得分:0)

我更喜欢第一个更适合我的目的,我假设“如果进程失败就在这里做点什么”我可以使用它的名称来杀死为foo调用这个包装脚本的脚本。

我认为第一种解决方案适用于多个孩子。无论如何,我必须快速完成这项工作,所以我使用了适用于我的应用程序的黑客:

我在主脚本中像往常一样在后台启动进程,然后使用$!得到它的pid(因为$!返回最后一个bg pid),睡眠2秒并做一个ps -e | grep pid根据(ps -e | grep pid)的返回值检查进程是否仍然存在。这对我很有用,因为如果我的后台进程中止,它会立即这样做(因为地址正在使用中)。

答案 2 :(得分:-2)

您可以将后台进程嵌套在脚本中。例如,如果要发送到后台的进程名为foo:

#!/bin/sh

foo

if [ $? ]
then 
    # do something here if process failed
fi

然后只在后台运行上面的脚本,而不是foo。如果你需要关闭它,你可以杀掉它,但只要foo继续运行它就永远不会终止,如果foo死了,你可以根据它的错误代码做任何你想做的事。