我正在尝试使用NSTask来运行UNIX'apropos'命令。这是我的代码:
NSTask *apropos = [[NSTask alloc] init];
NSPipe *pipe = [[NSPipe alloc] init];
[apropos setLaunchPath:@"/usr/bin/apropos"];
[apropos setArguments:[NSArray arrayWithObjects:@"filename", @"match", nil]];
[apropos setStandardOutput:pipe];
[apropos launch];
[apropos waitUntilExit];
问题是这永远不会回来。我也尝试使用Apple的示例代码(TaskWrapper)并返回输出(分三段),但它从不调用processFinished处理程序。
此外,appendOutput:处理程序接收重复项。因此,例如,如果apropos返回:
1 2 3 4 5
我可能会收到这样的信息:
1 2 3
1 2 3 4
5
(分为3个附加消息)。
我注意到Apropos以一种格式显示输出,可以在命令行中向上和向下滚动,而不是直接将数据直接输出到标准输出;如何通过NSTask和NSPipe可靠地读取它?
答案 0 :(得分:3)
我刚测试了这个程序,它运行正常:程序终止,/tmp/apropos.txt
包含apropos
的输出。
#import <Foundation/Foundation.h>
int main()
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSTask *apropos = [[[NSTask alloc] init] autorelease];
NSPipe *pipe = [[[NSPipe alloc] init] autorelease];
NSFileHandle *readHandle = [pipe fileHandleForReading];
[apropos setLaunchPath:@"/usr/bin/apropos"];
[apropos setArguments:[NSArray arrayWithObjects:@"filename", @"match", nil]];
[apropos setStandardOutput:pipe];
[apropos launch];
[apropos waitUntilExit];
NSString *output = [[[NSString alloc]
initWithData:[readHandle readDataToEndOfFile]
encoding:NSUTF8StringEncoding] autorelease];
[output writeToFile:@"/tmp/apropos.txt" atomically:YES
encoding:NSUTF8StringEncoding error:NULL];
[pool drain];
return 0;
}
您是否有机会使用NSLog()
来检查输出?如果是这样,您可能需要按照in this answer of mine to an NSTask related question的说明为stdin
设置管道。向NSLog()
发送数据的stderr
似乎会影响NSTask
。
答案 1 :(得分:2)
使用原始代码,我想是因为你没有读取命令的输出。管道只有有限的缓冲区大小,如果你没有读取任务的输出,它可能最终挂起等待缓冲区清空。我对您尝试的示例代码一无所知,所以我无法帮助。至于最后一个问题,apropos
仅在连接到终端时才使用寻呼机。你没有模仿终端,所以你不必担心。您可以通过在终端中运行apropos whatever | cat
并验证未调用寻呼机来证明这一点。