Here is my code:
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];
So I'm trying to replicate this:
cd /applications/jarvis/brain/
./server.sh
but using NSTask in objective-c.
For some reason though, when I run this code, stringRead, returns nothing. It should return what terminal is returning when I launch the .sh file. Correct?
Any ideas?
Elijah
The solution above is freezing because it's synchronous. Call to
[server waitUntilExit]
blocks the run loop until the tasks is done.Here's the async solution for getting the task output.
Probably you want to repeat the same above for
task.standardError
.IMPORTANT:
When your task terminates, you have to set readabilityHandler block to nil; otherwise, you'll encounter high CPU usage, as the reading will never stop.
This is all asynchronous (and you should do it async), so your method should have a ^completion block.
Xcode Bug
There's a bug in Xcode that stops it from printing any output after a a new task using standard output is launched (it collects all output, but no longer prints anything). You're going to have to call
[task setStandardInput:[NSPipe pipe]]
to get it to show output again (or, alternatively, have the task print to stderr instead of stdout).Suggestion for final code: