NSTask 代码,使用 objectivec,让命令行输出不再在 El Capitan 中工作

NSTask code, using objectivec, to get command line output no longer working in El Capitan

以下代码以前在OS X Yosemite中运行良好,但现在在OS X El Capitan 中通常不起作用,通常返回一个空字符串用于输出。

- (NSString*)runCommandLine:(NSString*)executable withArgs:(NSString*)arg {
    NSTask *commandLine = [[NSTask alloc] init];
    [commandLine setLaunchPath: executable];
    NSLog(@"CL EXECUTABLE: %@",executable);

    NSArray *arguments = [NSArray arrayWithObjects: arg, nil];
    [commandLine setArguments: arguments];
    NSLog(@"CL ARGUMENTS: %@",arguments);

    NSPipe *pipe = [NSPipe pipe];
    [commandLine setStandardOutput: pipe];  
    NSFileHandle *file = [pipe fileHandleForReading];    
    [commandLine launch];
    [commandLine waitUntilExit];

    NSData *data = [file readDataToEndOfFile];
    NSString *output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    NSLog(@"CL OUTPUT: %@",output);
    return output;
}

然后我使用以下示例调用它。没有错误,输出是简单的 "" 并且终止状态是 1:

NSString *adbLocation = [self runCommandLine:@"/usr/bin/which" withArgs: @"adb"];

这个 ls 示例运行良好(终止状态为 0)。

NSString *lsOutput = [[self runCommandLine:@"/usr/local/opt/coreutils/libexec/gnubin/ls" withArgs: @"-la"];

提前感谢您的建议!

NSString *whoamiOutput = [self runCommandLine:@"/usr/bin/whoami" withArgs: @""];

以上对应以下:

$ /usr/bin/whoami

对应的是:

$ /usr/bin/whoami ""

对我来说,在 Yosemite,这会向标准错误(不是标准输出)写入一条用法消息并以状态 1 退出。因此,这与您所看到的完全一致。

您需要一种不指定参数的方法。鉴于您用于设置任务的 arguments 属性 的代码,您可以只传递 nil 而不是您当前传递的空字符串。

(当然,正如 vadian 在评论中指出的那样,在真实的应用程序中这样做是荒谬的。希望这只是一个用于说明目的的示例。)

感谢 Ken 指引我正确的方向。

我通过以下方式解决了这个问题: NSString *executable = @"/bin/bash"

对于我的 which adb 示例:

NSArray *arguments = [NSArray arrayWithObjects: @"-l",@"-c",@"which adb",nil];