0

我的应用程序使用 NSTask 执行 shell 脚本,其中一个脚本启动 X11 应用程序(特别是meld)。

我原以为这会起作用:

#!/bin/bash
source ~/.profile                      # setup $PATH/etc
meld .

但它失败了:

gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
Traceback (most recent call last):
  File "/usr/local/bin/meld", line 132, in <module>
    gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
AttributeError: 'NoneType' object has no attribute 'append_search_path'

作为概念证明,我将脚本更改为此,效果很好:

#!/usr/bin/ruby

exec 'osascript -e \'tell app "Terminal" to do script "meld ' + Dir.pwd + '" in front window\''

有谁是造成问题的原因?这是我执行shell脚本的代码:

NSTask *task = [[NSTask alloc] init];
task.launchPath = self.scriptURL.path;
task.standardOutput = [NSPipe pipe];
task.currentDirectoryPath = workingDirectoryURL.path;

[task launch];
4

3 回答 3

2

X11 应用程序使用 DISPLAY 环境变量学习显示服务器的地址。

在 OS X 上,出于安全原因,DISPLAY 值是随机的,因此您无法对其进行硬编码,正如您所注意到的。相反,有一个 launchd 代理告诉 launchd 在启动进程时设置 DISPLAY。

在launchd 和meld 之间的某个地方,DISPLAY 的值正在被删除或覆盖。你的工作是找出在哪里。

  1. 确保已启动的代理正在运行。运行launchctl list并查找 org.macosforge.xquartz.startx。由于meld是从 Terminal.app 工作的,这部分可能是正确的。
  2. 确保在您的应用中设置了 DISPLAY。它应该列在[NSProcessInfo processInfo].environment.
  3. 确保在您启动的 NSTask 中设置了 DISPLAY。尝试/usr/bin/env使用 NSTask 运行,并确保 DISPLAY 出现在其输出中。
  4. 确保在您运行的脚本中设置了 DISPLAY。echo $DISPLAY在采购〜/ .profile之前和之后尝试。(有时 .profile 本身会将 DISPLAY 覆盖为不正确的值,因为有时在其他操作系统上这样做是正确的。)

编辑:这是我用来将 DISPLAY 从我的 GUI 应用程序复制到 shell 脚本的代码:

NSTask *task = ...
task.environment = [NSProcessInfo processInfo].environment;
[task.launch];
于 2013-03-27T06:36:32.997 回答
1

更改您的脚本以喷出环境变量并将“工作”与“不工作”进行比较。

在不同的执行模型中,shell 的初始化方式存在细微差别。几乎可以肯定,环境是问题的根源。

于 2013-03-27T03:12:49.347 回答
0

看看 man launchctl

launchctl 提交 ... -p /usr/local/bin/meld -- 。

已启动启动工作;这将为您设置某些环境变量,这些变量是每用户会话的一部分。

于 2013-03-27T06:18:38.490 回答