bash NSTask 没有从用户环境中获取 $PATH
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/386783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSTask not picking up $PATH from the user's environment
提问by Abizern
I don't know why this method returns a blank string:
我不知道为什么这个方法返回一个空字符串:
- (NSString *)installedGitLocation {
NSString *launchPath = @"/usr/bin/which";
// Set up the task
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:launchPath];
NSArray *args = [NSArray arrayWithObject:@"git"];
[task setArguments:args];
// Set the output pipe.
NSPipe *outPipe = [[NSPipe alloc] init];
[task setStandardOutput:outPipe];
[task launch];
NSData *data = [[outPipe fileHandleForReading] readDataToEndOfFile];
NSString *path = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return path;
}
If instead of passing @"git"as the argument, I pass @"which"I get /usr/bin/whichreturned as expected. So at least the principle works.
如果不是@"git"作为参数传递,而是通过,@"which"我会/usr/bin/which按预期返回。所以至少原理是有效的。
from the terminal
从终端
$ which which
$ /usr/bin/which
$
$ which git
$ /usr/local/git/bin/git
So it works there.
所以它在那里工作。
The only thing I can think of is that whichisn't searching through all the paths in my environment.
我唯一能想到的就是which没有在我的环境中搜索所有路径。
This is driving me crazy! Does anyone have any ideas?
这真让我抓狂!有没有人有任何想法?
EDIT:It looks like this is about setting up either NSTask or the user's shell (e.g., ~/.bashrc) so that the correct environment ($PATH) is seen by NSTask.
编辑:看起来这是关于设置 NSTask 或用户的 shell(例如,~/.bashrc),以便 NSTask 看到正确的环境($PATH)。
采纳答案by Chris Hanson
Running a task via NSTask uses fork()and exec()to actually run the task. The user's interactive shell isn't involved at all. Since $PATHis (by and large) a shell concept, it doesn't apply when you're talking about running processes in some other fashion.
通过 NSTask 运行任务使用fork()并exec()实际运行任务。根本不涉及用户的交互式 shell。由于$PATH(总的来说)是一个 shell 概念,因此当您谈论以其他方式运行进程时,它不适用。
回答by Vincent Gable
Try,
尝试,
[task setLaunchPath:@"/bin/bash"];
NSArray *args = [NSArray arrayWithObjects:@"-l",
@"-c",
@"which git",
nil];
[task setArguments: args];
This worked for me on Snow Leopard; I haven't tested on any other system. The -l (lowercase L) tells bash to "act as if it had been invoked as a login shell", and in the process it picked up my normal $PATH. This did not work for me if the launch path was set to /bit/sh, even with -l.
这对我在 Snow Leopard 上有用;我没有在任何其他系统上测试过。-l(小写 L)告诉 bash“就像它被作为登录 shell 调用一样”,并且在这个过程中它选择了我的正常 $PATH。如果启动路径设置为 /bit/sh,即使使用 -l,这对我也不起作用。
回答by codelogic
Is /usr/local/git/bin in your $PATH when you run the program? I think whichonly looks in the user's $PATH.
运行程序时,/usr/local/git/bin 是否在 $PATH 中?我认为which只在用户的 $PATH 中查找。
回答by Brian Webster
Take a look at the question Find out location of an executable file in Cocoa. It looks like the basic problem is the same. The answer unfortunately isn't nice and neat, but there's some useful info there.
看看问题Find out location of an executable file in Cocoa。看起来基本问题是一样的。不幸的是,答案不是很好和整洁,但那里有一些有用的信息。
回答by pableiros
In Swift NSTaskis replaced by Processbut this is what it works for me:
在 Swift 中NSTask被替换为Process但这对我有用:
let process = Process()
process.launchPath = "/bin/bash"
process.arguments = ["-l", "-c", "which git"]

