来自Console和Cocoa的不同$ PATH?

时间:2014-11-14 09:04:34

标签: objective-c macos bash cocoa environment-variables

好的,我必须遗漏一些非常简单的东西,但这里是:

  • 如果我在终端中echo $PATH,我的/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/drkameleon是正确的

  • 现在,如果我运行NSTask并尝试执行简单的bash脚本(/usr/bin/env bash myscript.sh)来回显$PATH,则会打印/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin

    < / LI>

(我甚至尝试使用getenv,或打印整个[[NSProcessInfo processInfo] environment]词典,但PATH变量只是......错误的)

发生了什么?如何访问终端中显示的真实 $PATH

1 个答案:

答案 0 :(得分:3)

通过NSTask执行命令时,不会启动bash,zshell或任何类型的shell。因此,当在终端中回显它们时,PATH(和其他环境变量)与环境变量不同。

原因: NSTask使用fork()exec()来执行命令。

恕我直言,这个问题有两种可能的解决方案。

<强> 1。您可以通过NSTask的setEnvironment:方法

设置所需的PATH

这是一些未经测试的示例代码,应该可以解决这个问题:

NSTask *task = //Configure your task
NSDictionary* env = [task environment];
NSString* currentPATH = env["PATH"];
NSString* yourPathExtension = @"/your/path";
env["PATH"] = (currentPATH != nil) ? [yourPath stringByAppendingFormat:@":%@", currentPATH] : yourPathExtension;
[task setEnvironment:env];

这会在NSTask的当前PATH之后添加:<old-PATH>

<强> 2。您可以在NSTask

中启动/bin/bash
task setLaunchPath:@"/bin/bash"];
NSArray *args = [NSArray arrayWithObjects:@"-l",
                 @"-c",
                 @"<your command here>",
                 nil];
[task setArguments: args];

此任务将通过~/.bashrc等配置的PATH启动/ bin / bash,并在bash中执行命令。

Pro:您的命令包含bash的所有常用环境变量

Con:您依赖于用户PATH变量,这可能与您的完全不同,这可能会导致意外行为。

哪种解决方案最适合您取决于您​​的使用案例。在您提供的示例中,两种方法都可以正常工作。

通常,根据NSTask和NSProcessInfo文档,环境变量等于应用程序启动过程的变量。因此,您可以在从bash启动应用程序时解决您的问题。