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 или оболочки пользователя (например, ~/.bashrc) так, чтобы NSTask видел правильную среду ($PATH).

4 ответа

Решение

Запуск задачи через NSTask использует fork() а также exec() на самом деле запустить задачу. Интерактивная оболочка пользователя вообще не задействована. поскольку $PATH Это (в общем и целом) концепция оболочки, она не применяется, когда вы говорите о запуске процессов каким-либо другим способом.

Пытаться,

    [task setLaunchPath: @ "/ bin / bash"];
    NSArray * args = [NSArray arrayWithObjects: @ "- l",
                     @"- с",
                     @"Какой мерзавец",
                     ноль];
    [task setArguments: args];

Это сработало для меня на Snow Leopard; Я не тестировал ни на одной другой системе. -L (строчная буква L) говорит bash "действовать так, как если бы он был вызван как оболочка входа в систему", и в процессе он взял мой обычный $PATH. Это не сработало для меня, если путь запуска был установлен на /bit/sh, даже с -l.

При запуске программы /usr/local/git/bin находится в вашем $PATH? Я думаю which только смотрит в $PATH пользователя.

Взгляните на вопрос. Узнайте расположение исполняемого файла в Какао. Похоже, основная проблема та же. Ответ, к сожалению, не очень хороший и аккуратный, но там есть некоторая полезная информация.

В Swift NSTask заменяется на Process но это то, что у меня работает:

let process = Process()
process.launchPath = "/bin/bash"
process.arguments = ["-l", "-c", "which git"]
Другие вопросы по тегам