Linux下如何获取nohup启动的后台Python进程退出码?
获取后台nohup启动的Python脚本的退出码
问题原因
你用反引号`包裹nohup命令并加&,会创建一个子shell执行nohup,导致Python进程是这个子shell的子进程,而非当前脚本shell的子进程,所以wait命令无法识别该PID。另外,用pgrep获取的PID也无法关联到当前shell的子进程关系,自然拿不到退出码。
解决方案一:直接捕获当前shell的后台进程PID(推荐)
去掉反引号,直接执行nohup命令并后台运行,用$!捕获最后一个后台进程的PID(该PID属于当前shell的子进程),之后用wait等待进程结束并获取退出码。
修改后的Shell脚本:
#!/bin/bash username="" while getopts 'u:' OPT; do case "$OPT" in u) username=$OPTARG;; esac done # 直接后台启动nohup命令,捕获PID nohup stdbuf -oL python3 -u pid_watch.py > "pid_watch.log" 2>&1 & PY_PID=$! # 等待进程结束,获取退出码 wait $PY_PID EXIT_CODE=$? echo "Python脚本PID: $PY_PID" echo "Python脚本退出码: $EXIT_CODE"
解决方案二:通过文件持久化退出码(适用于进程脱离当前shell的场景)
如果需要让Python脚本在当前shell退出后仍继续运行,无法用wait,可以让Python脚本在结束时将退出码写入指定文件,Shell脚本轮询检查进程状态,进程结束后读取文件中的退出码。
修改后的pid_watch.py:
import time import sys try: print("Hello World") time.sleep(180) print("End") # 正常退出,写入退出码0 with open("python_exit_code.txt", "w") as f: f.write(str(0)) except Exception as e: print(f"Error: {e}") # 异常退出,写入退出码1 with open("python_exit_code.txt", "w") as f: f.write(str(1)) sys.exit(1)
对应的Shell脚本:
#!/bin/bash username="" while getopts 'u:' OPT; do case "$OPT" in u) username=$OPTARG;; esac done # 启动Python脚本 nohup stdbuf -oL python3 -u pid_watch.py > "pid_watch.log" 2>&1 & PY_PID=$! echo "Python脚本PID: $PY_PID" # 轮询检查进程是否存活 while ps -p $PY_PID > /dev/null; do sleep 5 done # 读取退出码 EXIT_CODE=$(cat python_exit_code.txt) echo "Python脚本退出码: $EXIT_CODE" # 可选:清理退出码文件 rm -f python_exit_code.txt
关键说明
- 方案一的
wait命令只能在当前shell存活时使用,若当前shell退出,wait会中断,适合脚本需要等待Python进程完成再继续执行的场景。 - 方案二适合需要让Python脚本独立运行,后续再获取退出码的场景,通过文件传递状态。
内容的提问来源于stack exchange,提问作者puneet Shah
相关产品推荐
相关产品推荐

