I have something like:
- (NSString *)unixSinglePathCommandWithReturn:(NSString *)command
{
NSPipe *newPipe = [NSPipe pipe];
NSFileHandle *readHandle = [newPipe fileHandleForReading];
NSTask *unixTask = [[NSTask alloc] init];
[unixTask setStandardOutput:newPipe];
[unixTask setLaunchPath:@"/bin/sh"];
[unixTask setArguments:[NSArray arrayWithObjects:@"-c", command , nil]];
[unixTask launch];
[unixTask waitUntilExit];
NSString *output = [[NSString alloc] initWithData:[readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding];
return output;
}
But it doesn't work as expected. I call it when i click a button. If i remove the line with 'waitUntilExit' it works as expected, but only once. When it's there, it doesn't work. I tried also some basic commands like 'ls' 'ping -c1 google.com' and stuff like that, but i can't get it to work somehow. If you have some differ开发者_高级运维ent approach to run shell scripts in cocoa with receiving the response, please let me now. Thank you all :)
Hey, Kukosk. There’s a comment on CocoaDev about NSLog()
issues when running an NSTask. The fix is to set a pipe for stdin
before launching the task:
[task setStandardInput:[NSPipe pipe]];
If you’re relying on NSLog()
only to check whether the task has run, this might fix your problem. Alternatively, you could try to present output
in your GUI instead of using NSLog()
.
The problem is that you aren't emptying the output buffers of the task. You can't simply launch a task and waitUntilDone
unless the task also emits an extremely small amount of data.
waitUntilDone
will obviously not work at all with a task that never exits.
For a task that emits any quantity of output, you need to set it up such that the output is read as it is generated. Typically, you use readInBackgroundAndNotify
or a variant therein.
In any case, the top of the class description for NSTask
has both links to the conceptual guide and to a series of examples that cover this.
Ah, there's a very important line in the docs you seem to have missed, one of those irritations that NextStep seems to like: "An NSTask object can only be run once. Subsequent attempts to run the task raise an error."
So, bag the wait, and add [unixTask release] before the return. When you want to run it again, remake the task.
NSTimer is like this.
For different approaches to run shell scripts in Cocoa have a look at AMShellWrapper, PseudoTTY.app or OpenFileKiller!
http://www.cocoadev.com/index.pl?NSTask
精彩评论