如何获取经nohup启动并disown的后台进程返回码
获取disown + nohup后台进程的返回码
这是个很常见的痛点——当你用disown让进程脱离当前shell的作业列表后,wait $pid就失效了,因为shell不再把它当成自己的子进程跟踪,所以总会返回0。下面给你两种针对性的解决方案:
方案一:利用nohup特性,无需提前disown(推荐)
其实nohup已经帮你做了最关键的事:它会让目标进程忽略SIGHUP信号(这正是父进程退出时发给后台作业的终止信号)。所以不需要额外执行disown,进程在父进程意外退出时依然能存活,同时你可以正常用wait获取返回码:
nohup bash -c 'exit 123' "$@" >log.txt 2>&1 </dev/null & pid=$! # 等待进程结束,直接拿到返回码 wait $pid exit_code=$? # 这里可以根据需要处理返回码,比如直接退出脚本 exit $exit_code
这种方式最简单,既满足了“进程独立运行”的需求,又能直接获取返回码,完全不需要绕弯子。
方案二:必须用disown时,通过临时文件中转返回码
如果因为某些特殊原因(比如你的shell配置会自动清理未disown的后台作业)必须执行disown,那可以让目标进程在退出时把自己的返回码写入一个临时文件,之后读取这个文件拿到结果:
# 创建唯一的临时文件(用当前shell的PID避免冲突) exit_code_file="/tmp/process_exit_$$.tmp" # 启动进程时,在命令末尾添加写入返回码的操作 nohup bash -c ' # 这里放你的实际命令 exit 123 # 命令执行完成后,把返回码写入临时文件 echo $? > '"$exit_code_file"' ' "$@" >log.txt 2>&1 </dev/null & pid=$! # 从shell作业列表中移除进程 disown $pid # 跟踪日志直到进程终止(和你原来的逻辑一致) tail --pid=$pid -f log.txt # 读取返回码并清理临时文件 if [ -f "$exit_code_file" ]; then exit_code=$(cat "$exit_code_file") rm -f "$exit_code_file" else # 处理进程被强制杀死、未写入文件的异常情况 exit_code=1 fi exit $exit_code
注意事项
- 临时文件命名用
$$(当前shell的PID)可以避免多个脚本实例运行时互相干扰; - 如果进程被
kill -9强制终止,可能来不及写入返回码,所以要做好异常处理。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

