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

使用Python Subprocess.call打开多个Mac应用的问题及优化需求

解决Mac下Python脚本启动应用的阻塞与路径问题

核心问题梳理

你遇到的几个关键问题:

  1. 直接用subprocess.call会阻塞脚本,直到应用关闭才执行后续代码
  2. 带空格的应用路径在不用shell=True时的解析问题
  3. 需要等待应用加载完成而非关闭后再继续执行脚本

解决方案代码

方法1:用psutil检查进程加载状态(需额外安装库)

先安装依赖:

pip install psutil

脚本实现:

import subprocess
import psutil
import time

def wait_app_loaded(target_process_name):
    """等待应用进程启动并进入稳定状态"""
    while True:
        for proc in psutil.process_iter(["name", "status"]):
            if proc.info["name"] == target_process_name and proc.info["status"] == psutil.STATUS_RUNNING:
                # 通过内存变化判断是否加载完成(内存波动小于10%视为稳定)
                mem_initial = proc.memory_info().rss
                time.sleep(2)
                mem_latest = proc.memory_info().rss
                if abs(mem_latest - mem_initial) < mem_initial * 0.1:
                    return
        time.sleep(1)

# 启动Google Chrome(非阻塞,无需shell=True)
print("启动Chrome...")
chrome_proc = subprocess.Popen(
    ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT
)
wait_app_loaded("Google Chrome")
print("Chrome加载完成,继续执行")

# 启动MongoDB Compass
print("启动MongoDB Compass...")
compass_proc = subprocess.Popen(
    ["/Applications/MongoDB Compass.app/Contents/MacOS/MongoDB Compass"],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT
)
wait_app_loaded("MongoDB Compass")
print("所有应用加载完成")

方法2:用系统自带AppleScript检查(无需额外安装)

利用Mac原生的AppleScript判断应用是否就绪:

import subprocess

def wait_app_ready(app_display_name):
    """通过AppleScript等待应用启动并就绪"""
    script = f'''
    tell application "{app_display_name}"
        repeat until it is running
            delay 1
        end repeat
        repeat until frontmost of it is true
            delay 1
        end repeat
    end tell
    '''
    subprocess.run(["osascript", "-e", script], capture_output=True)

# 启动Chrome
chrome_proc = subprocess.Popen(
    ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT
)
wait_app_ready("Google Chrome")
print("Chrome已就绪")

# 启动MongoDB Compass
compass_proc = subprocess.Popen(
    ["/Applications/MongoDB Compass.app/Contents/MacOS/MongoDB Compass"],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT
)
wait_app_ready("MongoDB Compass")
print("MongoDB Compass已就绪")

关键说明

  1. 替换subprocess.call为Popen:call会等待子进程结束才返回,而Popen会立即启动进程并返回进程对象,实现非阻塞启动
  2. 路径处理:用列表形式传入命令参数,无需转义空格,直接写"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"即可,避免shell=True的安全风险和路径转义问题
  3. 等待加载完成:
    • 方法1通过psutil监控进程状态和内存变化,判断应用是否完成加载
    • 方法2利用AppleScript检查应用是否运行并处于前台,适合依赖GUI状态的应用
  4. 输出重定向:stdout=subprocess.DEVNULL和stderr=subprocess.STDOUT会屏蔽应用的终端输出,避免占用终端窗口

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:55:15