You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:50:17