【问题标题】:Return value of background process后台进程返回值
【发布时间】:2011-07-18 16:25:05
【问题描述】:
我需要根据后台进程的返回值采取一些措施,即如果它首先终止。
特别是:在理想操作中,我作为后台进程运行的服务器将永远保持运行。在这种情况下,将其保留在后台是有意义的,因为我希望我的 shell 脚本在生成服务器后执行其他操作。但是如果服务器异常终止,我希望最好使用服务器的退出返回值来决定是否终止我的主脚本。如果这不可能,我至少想中止主脚本,而不是在服务器出现故障时运行它。
我正在为 shell 脚本寻找具有异步回调性质的东西。一种解决方案是生成一个监视进程,该进程定期检查服务器是否出现故障。最好我想在主 shell 脚本本身中不这样做。
【问题讨论】:
标签:
unix
shell
background
return-value
【解决方案1】:
您可以通过捕获 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
【解决方案2】:
出于我的目的,我更喜欢第一个,我假设在“如果进程失败,请在此处执行某些操作”中,我可以通过使用它的名称来终止为 foo 调用此包装脚本的脚本。
我认为第一个解决方案适用于多个孩子。无论如何,我必须尽快完成这项工作,所以我使用了适用于我的应用程序的 hack:
我像往常一样在主脚本中在后台启动进程,然后使用 $!要获得它的 pid(因为 $! 返回最后一个 bg pid),睡眠 2 秒并执行 ps -e | grep pid 根据 (ps -e | grep pid) 的返回值检查进程是否仍然存在。这对我很有效,因为如果我的后台进程中止它会立即中止(因为地址正在使用中)。
【解决方案3】:
您可以将后台进程嵌套在脚本中。例如,如果您希望发送到后台的进程称为 foo:
#!/bin/sh
foo
if [ $? ]
then
# do something here if process failed
fi
然后在后台运行上面的脚本而不是foo。如果你需要关闭它,你可以杀死它,否则只要foo 继续运行它就永远不会终止,如果 foo 死了,你可以根据它的错误代码做任何你想做的事情。