使用NSTask:返回输出
您好我有以下代码:使用NSTask:返回输出
- (IBAction)runTask:(id)sender {
NSTask *proc;
NSPipe *output;
NSData *data;
NSString *buffer;
proc = [[NSTask alloc] init];
output = [[NSPipe alloc] init];
[proc setLaunchPath:@"/bin/sh"];
[proc setArguments:[NSArray arrayWithObjects: @"-c", @"/usr/bin/otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit | /usr/bin/awk 'NR>1{print $1}' | /usr/bin/sed -e '/@executable_path/d' -e 's/(.*)$//' -e 's/\\/Versions.*$//'", nil]];
[proc launch];
data = [[output fileHandleForReading] readDataToEndOfFile];
buffer = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"got: %@", buffer);
// Release
[proc release];
[output release];
[buffer release];
[data release];
}
的代码的目的是有点复杂,它使用otool得到它采用使用二进制那么共享库的列表sed和awk将其过滤为机器可读的格式。为了测试我已经使用了Mac OS X TextEdit.app的二进制文件。
的问题是代码运行和返回的输出,但随后冻结的应用程序。我通过它去逐行,发现这条线是问题:
数据= [[输出fileHandleForReading] readDataToEndOfFile];
该线本身正在记录输出到控制台,然后冷冻该应用。我通过删除该行之后的所有其他行来检查该行,并且它仍然记录输出并冻结。调试器中没有任何东西,并且如何解决这个问题的任何建议将不胜感激。
这个问题的解决办法很简单,
它是一个已知的bug被执行NSTask毕竟日志记录不工作。它正在返回一个输出,它只是不记录它。解决的办法是添加这一行:
[task setStandardInput:[NSPipe pipe]];
,一切工作正常:)
它看起来像你缺少一个
[proc setStandardOutput:output];
我添加了该行,但现在看起来我根本没有输出。 – indragie 2009-08-09 01:29:04
你在最后SED声明的末尾有一个额外的斜杠。一旦你删除它,脚本工作正常。
我不知道如果我删除了右斜线,我拿出一个在最后SED声明的最后,行是现在这个样子 [PROC setArguments:[NSArray的arrayWithObjects:@“ - C”,@ “在/ usr/bin中/ otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit |在/ usr /斌/的awk 'NR> 1 {打印$ 1}' |在/ usr/bin中/用sed -e“/ @ executable_path/d'-e's /(.*)$//'-e's/\\/Versions。* $ /'“,nil]]; 但我得到这个错误: 的sed:1:“S/\ /版本* $/\ N”:替代模式 – indragie 2009-08-09 02:36:46
哦,还有,我不认为它与命令本身的问题里面转义换行符,我尝试了一个非常简单的“ls/Volumes”,发生同样的事情,输出被返回,但应用程序冻结。我按照上一张海报的建议在setStandardOutput行中添加了内容,虽然解决了冻结问题,但不再有任何输出。 谢谢 – indragie 2009-08-09 02:39:38
PCWiz:啊,我在尝试命令之前忘记了避开反斜杠,并没有真正阅读它以查看最后一个模式应该结束的位置。最后的斜线属于那里。抱歉。 – 2009-08-09 02:59:17
输出应当与[NSPipe管(无主的),然后输出应该被设置为与[PROC setStandardOutput:输出]标准输出被创建
但你是崩溃的原因是因为你释放数据,其你没有拨出,新的或复制。请参阅memory management rules。
而且,看到Quickies for NSTask一个干净的执行这段代码。
我复制代码到一个命令行工具,补充丢失的'setStandardOutput:'消息,并运行它。它工作正常,除了在最后过度释放数据。 – 2009-08-09 05:34:35
“我通过删除该行后面的所有其他行来检查此行为...”我建议您改为抽样您的应用程序。见男子1样本。 – 2009-08-09 06:40:03