如何在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
相关产品推荐
相关产品推荐

