好的,我必须遗漏一些非常简单的东西,但这里是:
如果我在终端中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] environment]
词典,但PATH
变量只是......错误的)
发生了什么?如何访问终端中显示的真实 $PATH
?
答案 0 :(得分:3)
通过NSTask执行命令时,不会启动bash,zshell或任何类型的shell。因此,当在终端中回显它们时,PATH(和其他环境变量)与环境变量不同。
原因: NSTask使用fork()
和exec()
来执行命令。
<强> 1。您可以通过NSTask的setEnvironment:
方法
这是一些未经测试的示例代码,应该可以解决这个问题:
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启动应用程序时解决您的问题。