Swift Process调用Shell脚本无法获取XQuartz显示及安装检测问题
解决Swift调用Shell脚本无法获取XQuartz显示的问题
嘿,我太懂你遇到的这个坑了——终端里跑脚本XQuartz正常启动,换成Swift的Process调用就不行对吧?核心原因其实很简单:终端会自动继承XQuartz的环境变量,但Swift的Process默认是干净的执行环境,缺少关键的DISPLAY变量。给你两个靠谱的解决方法:
方法1:手动注入DISPLAY环境变量
XQuartz启动后,默认的显示标识是:0,你可以直接在Swift代码里给Process补上这个环境变量:
let process = Process() process.executableURL = URL(fileURLWithPath: "/bin/sh") let startScriptURL = Bundle.main.url(forResource: "run", withExtension: "sh") guard let startScriptPath = startScriptURL?.path else { return } process.arguments = [startScriptPath] // 添加上XQuartz必需的DISPLAY变量 var env = ProcessInfo.processInfo.environment env["DISPLAY"] = ":0" process.environment = env do { try process.run() } catch let error { print(error) }
或者偷懒一点,直接在你的run.sh脚本开头加上这行:
#!/bin/sh export DISPLAY=:0 /opt/X11/bin/xeyes
方法2:动态获取正确的DISPLAY值
如果担心默认的:0不对(比如用户开了多个XQuartz实例,虽然这种情况很少见),可以通过launchctl获取当前用户的真实DISPLAY值,脚本这么写更稳妥:
#!/bin/sh # 从系统服务中获取当前用户的DISPLAY变量 export DISPLAY=$(launchctl getenv DISPLAY) # 先检查XQuartz是否在运行 if [ -z "$DISPLAY" ]; then echo "XQuartz还没启动哦!" exit 1 fi /opt/X11/bin/xeyes
检测XQuartz是否安装的最佳方式
只检查xterm存在其实不太靠谱哦——虽然XQuartz确实会自带xterm,但难保其他第三方工具也会装个同名程序。给你两个更准确的检测方法:
- 检查XQuartz应用本体:XQuartz作为Mac原生应用,安装后肯定在
/Applications/Utilities/XQuartz.app,直接检查这个目录是否存在就100%准确。 - 检查核心X11服务程序:XQuartz的核心是
/opt/X11/bin/Xorg,这个是XQuartz独有的组件,不会有其他工具随便安装。
Shell脚本里的检测代码:
# 方法1:检查XQuartz应用是否存在 if [ -d "/Applications/Utilities/XQuartz.app" ]; then echo "XQuartz已经安装啦" else echo "还没装XQuartz哦" exit 1 fi # 方法2:检查核心Xorg程序 if [ -x "/opt/X11/bin/Xorg" ]; then echo "XQuartz已安装" else echo "未安装XQuartz" exit 1 fi
Swift代码里的检测方式:
let xQuartzAppPath = "/Applications/Utilities/XQuartz.app" if FileManager.default.fileExists(atPath: xQuartzAppPath) { print("XQuartz已安装") } else { print("请先安装XQuartz") }
这样检测比单纯查xterm要可靠得多~
内容的提问来源于stack exchange,提问作者doom4
相关产品推荐
相关产品推荐

