簡體   English   中英

NSTask NSPipe - 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM