好吧,我一定错过了一些非常简单的东西,但这就是:
如果我在终端中
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
(我什至尝试过使用getenv
,或打印整个[[NSProcessInfo processInfo]环境]
字典,但是PATH
变量根本就是……错误)
发生什么事了?我如何才能访问终端中看到的真实 $PATH
?
最佳答案
通过 NSTask 执行命令时,不会启动 bash、zshell 或您正在使用的任何类型的 shell。因此,在终端中回显 PATH(和其他环境变量)时,它们与您的环境变量不同。
原因: NSTask 使用 fork()
和exec()
用于命令执行。
恕我直言,这个问题有两种可能的解决方案。
<强>1。您可以通过 setEnvironment:
设置所需的 PATH NSTask的方法
这是一些未经测试的示例代码,应该可以解决问题:
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];
这增加了 :<old-PATH>
在 NSTask 的当前路径之后。
<强>2。您可以开始/bin/bash
在 NSTask 内
task setLaunchPath:@"/bin/bash"];
NSArray *args = [NSArray arrayWithObjects:@"-l",
@"-c",
@"<your command here>",
nil];
[task setArguments: args];
此任务将使用通过 ~/.bashrc
配置的 PATH 启动/bin/bash等等并在 bash 中执行命令。
优点:你的命令拥有 bash 的所有常用环境变量
缺点:您依赖于用户的 PATH 变量,该变量可能与您的变量完全不同,这可能会导致意外的行为。
哪种解决方案最适合您取决于您的用例。在您提供的示例中,两种方法都应该可以正常工作。
一般来说,根据 NSTask 和 NSProcessInfo 文档,环境变量等于启动应用程序的进程的变量。因此,从 bash 启动应用程序时您可能会解决问题。
关于objective-c - $PATH 与 Console 和 Cocoa 不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26926338/