![](/img/trans.png)
[英]NSTask and NSPipe example to comunicate with the command line objective-c
[英]NSTask NSPipe - objective c command line help
這是我的代碼:
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];
所以我試圖復制這個:
cd /applications/jarvis/brain/
./server.sh
但在objective-c中使用NSTask。
但是出於某種原因,當我運行此代碼時,stringRead不會返回任何內容。 當我啟動.sh文件時,它應該返回返回的終端。 正確?
有任何想法嗎?
以利亞
Xcode Bug
Xcode中存在一個錯誤,在啟動使用標准輸出的新任務后,它會阻止它打印任何輸出(它收集所有輸出,但不再打印任何內容)。 您將不得不調用[task setStandardInput:[NSPipe pipe]]
使其再次顯示輸出(或者,將任務打印到stderr而不是stdout)。
建議最終代碼:
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.
上面的解決方案是凍結的,因為它是同步的。 調用[server waitUntilExit]
阻止運行循環,直到任務完成。
這是獲取任務輸出的異步解決方案。
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
重復上面的相同task.standardError
。
重要:
當您的任務終止時,您必須將readabilityHandler塊設置為nil; 否則,您將遇到高CPU使用率,因為讀數永遠不會停止。
[task setTerminationHandler:^(NSTask *task) {
// do your stuff on completion
[task.standardOutput fileHandleForReading].readabilityHandler = nil;
[task.standardError fileHandleForReading].readabilityHandler = nil;
}];
這都是異步的(你應該做異步),所以你的方法應該有一個^完成塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.