NSTask 未从用户环境中获取 $PATH
我不知道为什么这个方法返回一个空字符串:
- (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;
}
如果我不传递 @"git"
作为参数,而是传递 @"which"
我得到 /usr/bin/which
按预期返回。 所以至少这个原则是有效的。
从终端
$ which which
$ /usr/bin/which
$
$ which git
$ /usr/local/git/bin/git
所以它在那里工作。
我唯一能想到的是 which
没有搜索我的环境中的所有路径。
这真让我抓狂! 有人有什么想法吗?
编辑:看起来这是关于设置 NSTask 或用户的 shell(例如 ~/.bashrc),以便 NSTask 看到正确的环境($PATH)。
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/which
returned as expected. So at least the principle works.
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 which
isn't searching through all the paths in my environment.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
尝试一下,
这对我在 Snow Leopard 上有用; 我没有在任何其他系统上进行过测试。 -l(小写 L)告诉 bash “就像它被作为登录 shell 一样被调用一样”,并在此过程中它选择了我的正常 $PATH。 如果启动路径设置为 /bit/sh,即使使用 -l,这对我也不起作用。
Try,
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.
通过 NSTask 运行任务使用
fork()
和exec()
来实际运行任务。 根本不涉及用户的交互式 shell。 由于$PATH
(总的来说)是一个 shell 概念,因此当您谈论以其他方式运行进程时,它不适用。Running a task via NSTask uses
fork()
andexec()
to actually run the task. The user's interactive shell isn't involved at all. Since$PATH
is (by and large) a shell concept, it doesn't apply when you're talking about running processes in some other fashion.当你运行程序时, /usr/local/git/bin 是否在你的 $PATH 中? 我认为
which
只在用户的 $PATH 中查找。Is /usr/local/git/bin in your $PATH when you run the program? I think
which
only looks in the user's $PATH.看一下问题 找出可执行文件的位置可可。 看起来基本问题是一样的。 不幸的是,答案并不好而且简洁,但其中有一些有用的信息。
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.
在 Swift 中,
NSTask
被Process
取代,但这对我来说是有效的:In Swift
NSTask
is replaced byProcess
but this is what it works for me: