13

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

- (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)。

4

5 回答 5

23

尝试,

    [task setLaunchPath:@"/bin/bash"];
    NSArray *args = [NSArray arrayWithObjects:@"-l",
                     @“-C”,
                     @"哪个 git",
                     零];
    [任务集参数:参数];

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.

于 2009-11-30T04:39:01.753 回答
13

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

于 2008-12-23T02:17:05.707 回答
2

运行程序时 /usr/local/git/bin 是否在 $PATH 中?我认为which只查看用户的 $PATH。

于 2008-12-22T17:29:19.827 回答
1

看看问题Find out location of an executable file in Cocoa。看起来基本问题是一样的。不幸的是,答案不是很好和整洁,但那里有一些有用的信息。

于 2008-12-22T18:48:15.860 回答
1

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"]
于 2019-11-12T23:48:31.710 回答