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];
以下代码以前在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];