NSTask 未从用户环境中获取 $PATH

发布于 2024-07-11 11:53:34 字数 1072 浏览 10 评论 0原文

我不知道为什么这个方法返回一个空字符串:

- (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

↘紸啶 2024-07-18 11:53:34

尝试一下,

    [task setLaunchPath:@"/bin/bash"];
    NSArray *args = [NSArray arrayWithObjects:@"-l",
                     @"-c",
                     @"which git",
                     nil];
    [task setArguments: args];

这对我在 Snow Leopard 上有用; 我没有在任何其他系统上进行过测试。 -l(小写 L)告诉 bash “就像它被作为登录 shell 一样被调用一样”,并在此过程中它选择了我的正常 $PATH。 如果启动路径设置为 /bit/sh,即使使用 -l,这对我也不起作用。

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.

层林尽染 2024-07-18 11:53:34

通过 NSTask 运行任务使用 fork()exec() 来实际运行任务。 根本不涉及用户的交互式 shell。 由于 $PATH (总的来说)是一个 shell 概念,因此当您谈论以其他方式运行进程时,它不适用。

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 $PATH is (by and large) a shell concept, it doesn't apply when you're talking about running processes in some other fashion.

女皇必胜 2024-07-18 11:53:34

当你运行程序时, /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.

胡大本事 2024-07-18 11:53:34

看一下问题 找出可执行文件的位置可可。 看起来基本问题是一样的。 不幸的是,答案并不好而且简洁,但其中有一些有用的信息。

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.

清旖 2024-07-18 11:53:34

在 Swift 中,NSTaskProcess 取代,但这对我来说是有效的:

let process = Process()
process.launchPath = "/bin/bash"
process.arguments = ["-l", "-c", "which git"]

In Swift NSTask is replaced by Process but this is what it works for me:

let process = Process()
process.launchPath = "/bin/bash"
process.arguments = ["-l", "-c", "which git"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文