我正在使用NSUserUnixTask
在我的沙盒应用上运行未经过沙盒的NSTask
。但是,我的代码会在调用[NSFileHandle readDataToEndOfFile]
时挂起。如果我删除这些调用它完美地工作。如果我将[NSFileHandle readDataToEndOfFile]
替换为[NSFileHandle availableData]
,它也会挂起。
以下是代码:
NSUserUnixTask* unixTask = [[NSUserUnixTask alloc] initWithURL: [NSURL fileURLWithPath: path] error: nil];
// Create error file handle
NSFileHandle* errorFH = [NSFileHandle fileHandleWithStandardError];
[unixTask setStandardError: errorFH];
// Create output file handle
NSFileHandle* outputFH = [NSFileHandle fileHandleWithStandardOutput];
[unixTask setStandardOutput: outputFH];
// Run task with termination handler
[unixTask executeWithArguments: nil completionHandler: ^(NSError* error2) {
// Save output
NSString* output = [[NSString alloc] initWithData: [outputFH readDataToEndOfFile] encoding: NSUTF8StringEncoding];
if ([output length]) { // <-- Execution never reaches this line when the block is called
NSLog(@"%@", output);
}
// Read error 1
NSString* error1 = [[NSString alloc] initWithData: [errorFH readDataToEndOfFile] encoding: NSUTF8StringEncoding];
if ([error1 length]) {
NSLog(@"%@", error1);
}
// Read error 2
if (error2) {
NSLog(@"%@", error2);
}
}];
Xcode的控制台上没有记录任何内容,但如果我打开Console.app,我会看到这一行:
Warning: Exception caught during decoding of received reply to message 'executeScript:interpreter:arguments:standardInput:standardOutput:standardError::', dropping incoming message and calling failure block.
Exception: *** -[NSConcreteFileHandle readDataOfLength:]: Bad file descriptor
嗯,我该怎么解决这个问题?在我的应用程序使用沙盒之前,我将NSPipe
与NSTask
结合使用,一切正常,但现在NSUserUnixTask
需要使用NSFileHandle
而我认为我的问题仅仅是因为我没有正确使用它。但我仍然不知道我做错了什么。
答案 0 :(得分:2)
在我看来,您必须使用NSPipe
从NSUserUnixTask
读取stderr和stdout,就像使用NSTask
一样。
我用“/ bin / ls”任务测试了它,它产生了预期的输出:
NSPipe *outPipe = [NSPipe pipe];
NSPipe *errPipe = [NSPipe pipe];
NSString *path = @"/bin/ls";
NSUserUnixTask *unixTask = [[NSUserUnixTask alloc] initWithURL: [NSURL fileURLWithPath: path] error: nil];
[unixTask setStandardOutput:[outPipe fileHandleForWriting]];
[unixTask setStandardError:[errPipe fileHandleForWriting]];
[unixTask executeWithArguments:nil completionHandler:^(NSError *error) {
NSString *output = [[NSString alloc] initWithData: [[outPipe fileHandleForReading] readDataToEndOfFile] encoding: NSUTF8StringEncoding];
NSLog(@"stdout: %@", output);
NSString *error1 = [[NSString alloc] initWithData: [[errPipe fileHandleForReading] readDataToEndOfFile] encoding: NSUTF8StringEncoding];
NSLog(@"stderr: %@", error1);
}];