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

如何通过Python脚本在Gnome Terminal中运行命令并等待进程终止

解决方案

方案1:利用Gnome Terminal的--wait参数

Gnome Terminal 3.28及以上版本支持--wait参数,启用后终端会保持打开状态,直到内部执行的命令完全结束。你可以直接让终端运行目标可执行文件,通过wait()等待终端退出,间接实现等待目标程序完成的效果。

示例代码:

import subprocess
from concurrent.futures import ThreadPoolExecutor

def run_in_terminal(executable_path):
    # 启动Gnome Terminal并执行目标程序,--wait参数让终端等待程序结束
    proc = subprocess.Popen([
        "gnome-terminal",
        "--wait",
        "--",  # 分隔终端自身参数与要执行的命令
        executable_path
    ])
    proc.wait()
    # 程序执行完成后的后续操作
    print(f"{executable_path} 已执行完毕")

if __name__ == "__main__":
    # 替换为你的可执行文件路径列表
    executables = ["./test1", "./test2", "./test3"]
    with ThreadPoolExecutor(max_workers=len(executables)) as executor:
        executor.map(run_in_terminal, executables)

如果可执行文件需要传递参数,直接追加到executable_path后即可,例如:"./test1", "arg1", "arg2"。

方案2:通过PID监控目标进程

如果你的Gnome Terminal版本不支持--wait参数,可以让终端启动程序时将进程PID写入临时文件,再由Python脚本读取PID并监控进程状态。

示例代码:

import subprocess
import os
import tempfile
from concurrent.futures import ThreadPoolExecutor
import time

def run_and_monitor(executable_path):
    # 创建临时文件用于存储进程PID
    with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmpf:
        tmp_path = tmpf.name

    # 启动终端,让目标程序将自身PID写入临时文件后执行
    subprocess.Popen([
        "gnome-terminal",
        "--",
        "bash", "-c",
        f"echo $$ > {tmp_path}; exec {executable_path}"
    ])

    # 等待临时文件生成并读取PID
    while not os.path.exists(tmp_path):
        time.sleep(0.1)
    with open(tmp_path, 'r') as f:
        pid = int(f.read().strip())
    os.unlink(tmp_path)  # 读取后删除临时文件

    # 监控进程直到结束
    try:
        os.waitpid(pid, 0)
    except ChildProcessError:
        # 处理进程已提前结束的情况
        pass
    print(f"{executable_path} 已执行完毕")

if __name__ == "__main__":
    executables = ["./test1", "./test2", "./test3"]
    with ThreadPoolExecutor(max_workers=len(executables)) as executor:
        executor.map(run_and_monitor, executables)

这里通过exec命令让目标程序替换当前shell进程,确保$$获取到的就是目标程序的真实PID,避免监控到shell进程而非目标进程的问题。

方案3:使用screen工具(备选)

如果上述方案都不适用,可以借助screen工具在终端中启动程序,再通过PID监控进程状态:

import subprocess
import os
from concurrent.futures import ThreadPoolExecutor

def run_with_screen(executable_path):
    # 用screen创建后台会话并启动程序
    session_name = f"exec_session_{os.path.basename(executable_path)}"
    subprocess.Popen([
        "screen", "-dmS", session_name,
        executable_path
    ])
    # 获取screen会话对应的进程PID
    pid = int(subprocess.check_output([
        "pgrep", "-f", f"screen.*{session_name}"
    ]).strip())
    os.waitpid(pid, 0)
    print(f"{executable_path} 已执行完毕")

if __name__ == "__main__":
    executables = ["./test1", "./test2", "./test3"]
    with ThreadPoolExecutor(max_workers=len(executables)) as executor:
        executor.map(run_with_screen, executables)

该方案需要系统预先安装screen工具,且PID匹配逻辑可能需要根据实际情况调整,可靠性略低于前两种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:33:35