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

如何在Python中启动新Terminal执行Shell脚本并获取退出码

解决Python调用gnome-terminal执行脚本并获取退出码的问题

原代码的核心问题在于:gnome-terminal是独立的终端进程,它启动后会立即返回退出状态,你拿到的process.returncode是终端程序的退出码(一般为0,只要终端成功启动),而不是目标脚本myscript.sh的退出码。

下面是两种可行的解决方案:

方案一:用临时文件存储脚本退出码

通过让脚本执行完成后将自身退出码写入临时文件,Python端轮询读取该文件来获取结果:

import subprocess
import tempfile
import os
import time

# 创建临时文件用于存储退出码(关闭后不自动删除)
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
    exit_code_path = tmp_file.name

# 构造终端启动命令:执行脚本后将退出码写入临时文件
launch_cmd = [
    'gnome-terminal',
    '-x',
    'bash', '-c', f'./myscript.sh; echo $? > {exit_code_path}'
]

# 启动终端进程,等待终端启动完成
terminal_process = subprocess.Popen(launch_cmd)
terminal_process.wait()

# 轮询等待脚本执行完成并写入退出码
while not os.path.exists(exit_code_path) or os.path.getsize(exit_code_path) == 0:
    time.sleep(0.5)

# 读取并转换退出码
with open(exit_code_path, 'r') as f:
    script_exit_code = int(f.read().strip())

print(f"脚本退出码: {script_exit_code}")

# 清理临时文件
os.unlink(exit_code_path)

方案二:跟踪脚本进程PID(进阶)

如果需要更精准地监控脚本运行状态,可以让脚本启动时写入自身PID,Python通过PID判断脚本是否结束,再读取退出码:

import subprocess
import tempfile
import os
import time

# 创建两个临时文件:一个存PID,一个存退出码
with tempfile.NamedTemporaryFile(mode='w', delete=False) as pid_file:
    pid_path = pid_file.name
with tempfile.NamedTemporaryFile(mode='w', delete=False) as exit_file:
    exit_code_path = exit_file.name

# 构造命令:启动脚本时写入PID,执行完成后写入退出码
launch_cmd = [
    'gnome-terminal',
    '-x',
    'bash', '-c', f'echo $$ > {pid_path}; ./myscript.sh; echo $? > {exit_code_path}'
]

# 启动终端
subprocess.Popen(launch_cmd).wait()

# 等待PID文件生成并读取PID
while not os.path.exists(pid_path) or os.path.getsize(pid_path) == 0:
    time.sleep(0.5)
with open(pid_path, 'r') as f:
    script_pid = int(f.read().strip())

# 轮询检查脚本进程是否存活
while True:
    try:
        # 发送0信号判断进程是否存在
        os.kill(script_pid, 0)
        time.sleep(0.5)
    except OSError:
        # 进程已结束,读取退出码
        break

# 读取退出码
with open(exit_code_path, 'r') as f:
    script_exit_code = int(f.read().strip())

print(f"脚本退出码: {script_exit_code}")

# 清理临时文件
os.unlink(pid_path)
os.unlink(exit_code_path)

注意事项

  • 确保myscript.sh有可执行权限(可通过chmod +x myscript.sh设置)
  • 如果脚本执行时间较长,可适当调整轮询的time.sleep()间隔,平衡资源占用和响应速度

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:47:23