开发者

Execute shell script from cocoa (obj.c) with response

开发者 https://www.devze.com 2023-02-03 18:01 出处:网络
I have something like: - (NSString *)unixSinglePathCommandWithReturn:(NSString *)command { NSPipe *newPipe = [NSPipe pipe];

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号