Mac OS 10.15.4下Python3.7 Idle用subprocess调用应用报权限与文件错误
报错原因与Mac系统应用正确调用方式
两类报错的核心原因
PermissionError: [Errno 13] Permission denied:macOS中后缀为.app的应用不是独立可执行文件,是遵循系统Bundle规范的目录结构。subprocess.Popen默认会将传入路径直接作为可执行程序发起执行,当路径指向.app外层目录时,系统会拦截这种对目录的直接执行操作,因此抛出权限拒绝错误。FileNotFoundError: [Errno 2] No such file or directory:路径开头的/代表绝对路径,指向系统根目录下的对应位置;去掉开头/后路径会变为相对路径,Python进程会从自身当前工作目录(一般是运行IDLE时的用户家目录)下查找目标,自然无法定位到系统根目录下的应用内容。替换为TextEdit后同样触发该错误,有两种叠加原因:一是路径拼写可能存在误差(比如大小写错误、找错了应用存放目录),二是即使路径完全正确,subprocess仍会将.app外层目录识别为非可执行的目录对象,部分校验逻辑会将这类无执行权限的路径判定为不存在,最终抛出文件找不到错误。
正确的subprocess调用Mac系统应用的方法
方法1(最推荐):调用macOS原生open命令
open是macOS内置的专门用于启动.app格式应用的命令行工具,完全适配系统的权限校验逻辑,稳定性最高,示例代码:
import subprocess # 启动Safari subprocess.Popen(['open', '/Applications/Safari.app']) # 启动TextEdit subprocess.Popen(['open', '/Applications/TextEdit.app'])
注意:传参时需要将命令和每个参数拆分为列表元素传递,不要拼接成整段字符串传入,否则涉及带空格的应用路径时极易触发路径解析错误。
方法2:直接调用应用包内的实际可执行二进制
如果不需要走系统open逻辑,可以定位.app目录内部的真正可执行文件路径调用,系统应用的可执行文件统一存放在应用包内的Contents/MacOS/路径下,以Safari为例的可执行路径为/Applications/Safari.app/Contents/MacOS/Safari,示例代码:
import subprocess subprocess.Popen('/Applications/Safari.app/Contents/MacOS/Safari')
注意:这种启动方式不会加载系统应用的默认环境变量和权限配置,容易出现应用功能异常、权限不足的问题,仅适合特殊调试场景使用。
常见避坑提醒
- 定位系统应用时必须使用根目录开头的绝对路径,不要省略开头的
/使用相对路径 - 不要直接将
.app的外层目录路径作为subprocess的执行目标,除非明确使用open命令包裹路径参数
内容的提问来源于stack exchange,提问作者fishbacp
相关产品推荐
相关产品推荐

