The best way to call a shell-command from Coca is by using an NSTask. Here are the three resources on using an NSTask that I found the most helpful:
CocoDev’s write up
A few quick exaples
NSTask Class Refrence
And here is some sample code to do it for you. You are free to use this code however you please, but attribution is always appreciated. The two principle functions are:
+ (NSString*) executeShellCommandSynchronously:(NSString*)command
executes the command “command” with sh, wait until it finishes, and return whatever it printed to stdout and stderr as an NSString.
CAUTION: may deadlock under some circumstances if the output gets so big it fills the pipe. See http://dev.notoptimal.net/search/label/NSTask for an overview of the problem, and a solution. I have not experienced the problem myself, so I can’t comment.
executeShellCommandAsynchronously:
will have sh execute command
in the background, without blocking anything.
For quick hacks, the POSIX int system(const char* command)
function, might be a good one-line solution. It synchronously evaluates command
with sh.
Enjoy!
EDITED 2009-11-29: this code probably won’t have the same $PATH
you would get if you used Terminal. See this question on stackoverflow for more details. A solution that seems to work is to do,
[task setLaunchPath:@"/bin/bash"]; NSArray *args = [NSArray arrayWithObjects:@"-l", @"-c", commandlineHere, nil]; [task setArguments: args];
This launches bash
(not in sh
compatibility mode), and -l (lowercase L) tells it to “act as if it had been invoked as a login shell”. I haven’t tested this on systems where bash
isn’t the default shell. There are lots of ways $PATH
could be set, and I haven’t tested them all. But you are almost certainly going to be OK if everything you refer to is in /usr/bin:/bin:/usr/sbin:/sbin
.