首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSTask NSPipe - objective c命令行帮助

NSTask NSPipe - objective c命令行帮助
EN

Stack Overflow用户
提问于 2010-08-10 05:03:12
回答 2查看 11.2K关注 0票数 10

下面是我的代码:

代码语言:javascript
复制
task = [[NSTask alloc] init];
[task setCurrentDirectoryPath:@"/applications/jarvis/brain/"];
[task setLaunchPath:@"/applications/jarvis/brain/server.sh"];

NSPipe * out = [NSPipe pipe];
[task setStandardOutput:out];

[task launch];
[task waitUntilExit];
[task release];

NSFileHandle * read = [out fileHandleForReading];
NSData * dataRead = [read readDataToEndOfFile];
NSString * stringRead = [[[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding] autorelease];

所以我试着复制这个:

代码语言:javascript
复制
cd /applications/jarvis/brain/
./server.sh

但在objective-c中使用NSTask。

但是,由于某些原因,当我运行这段代码时,stringRead什么也不返回。当我启动.sh文件时,它应该返回终端返回的内容。对,是这样?

有什么想法吗?

以利亚

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-13 03:52:31

Xcode错误

Xcode中有一个bug,在使用标准输出的新任务启动后,它停止打印任何输出(它收集所有输出,但不再打印任何输出)。您必须调用[task setStandardInput:[NSPipe pipe]]让它再次显示输出(或者,让任务打印到stderr而不是stdout)。

最终代码的建议:

代码语言:javascript
复制
NSTask *server = [NSTask new];
[server setLaunchPath:@"/bin/sh"];
[server setArguments:[NSArray arrayWithObject:@"/path/to/server.sh"]];
[server setCurrentDirectoryPath:@"/path/to/current/directory/"];

NSPipe *outputPipe = [NSPipe pipe];
[server setStandardInput:[NSPipe pipe]];
[server setStandardOutput:outputPipe];

[server launch];
[server waitUntilExit]; // Alternatively, make it asynchronous.
[server release];

NSData *outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile];
NSString *outputString = [[[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding] autorelease]; // Autorelease optional, depending on usage.
票数 20
EN

Stack Overflow用户

发布于 2013-04-29 17:06:39

上面的解决方案是冻结的,因为它是同步的。调用[server waitUntilExit]会阻止运行循环,直到任务完成。

下面是获取任务输出的异步解决方案。

代码语言:javascript
复制
task.standardOutput = [NSPipe pipe];
[[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
    NSData *data = [file availableData]; // this will read to EOF, so call only once
    NSLog(@"Task output! %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

    // if you're collecting the whole output of a task, you may store it on a property
    [self.taskOutput appendData:data];
}];

您可能希望对task.standardError重复上述操作。

重要信息:

当您的任务终止时,您必须将readabilityHandler块设置为空;否则,您将遇到高CPU使用率,因为读取永远不会停止。

代码语言:javascript
复制
[task setTerminationHandler:^(NSTask *task) {

    // do your stuff on completion

    [task.standardOutput fileHandleForReading].readabilityHandler = nil;
    [task.standardError fileHandleForReading].readabilityHandler = nil;
}];

这都是异步的(你应该异步地做),所以你的方法应该有一个^完成块。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3444178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档