Reputation: 1335
I'm writing a command line helper for one of my cocoa apps. This helper tool is supposed to execute an instance of shell ( /bin/sh ) using NSTask
. As you all know it's possible to execute sh
taking advantage of -c
, you can pass one or more command as an argument to be executed.
For example running /bin/sh -c "networksetup -setwebproxystate Wi-Fi on"
executes networksetup -setwebproxystate Wi-Fi on
.
Now, Here's the question :
When I set the launch path to sh
( [task setLaunchPath:@"/bin/sh"]
) , and then set Arguments as following :
cmd = "-c,\\\"networksetup\\_-setwebproxystate\\_Wi-Fi\\_on\\\"";
stringArguments = [NSMutableString stringWithFormat:@"%s", cmd.c_str()];
stringArguments = [[stringArguments stringByReplacingOccurrencesOfString:@"_" withString:@" "] mutableCopy];
arguments = [stringArguments componentsSeparatedByString:@","];
[task setArguments:arguments];
I see that somehow -c
argument is skipped, because I get the following error :
/bin/sh: "networksetup -setwebproxystate Wi-Fi on": command not found
and that's because "networksetup -setwebproxystate Wi-Fi on"
is executed directly not as an argument after sh -c
.
I know I couldn't explain in the clearest way possible, but hope I could deliver what I meant.
I tried almost everything came to my mind, but I'm stuck with this. Any suggestions is really appreciated.
Upvotes: 0
Views: 653
Reputation: 53000
When entering a command at the shell prompt double-quotes are used to pass a string as a single argument when it would otherwise be passed as multiple arguments. When using NSTask
(or function/system calls in the exec
family) you pass each argument individually, the shell does not need to parse a command line, and so double quotes are not required. The following fragment:
NSTask *task = [NSTask new];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:@[@"-c", @"networksetup -setwebproxystate Wi-Fi on"]];
[task launch];
will do the task you want. The two arguments are passed using a literal array expression, each argument is just a string and may contain spaces etc.
HTH
Upvotes: 0
Reputation: 923
The problem is in your amazingly convoluted way of specifying the command string. NSTask does not need quotes around the arguments. You are ending up with arguments containing this:
[0] ==> -c
[1] ==> "networksetup -setwebproxystate Wi-Fi on"
Note the double-quotes. Why not just use
arguments = [NSArray arrayWithObjects:
@"-c",
@"networksetup -setwebproxystate Wi-Fi on",
nil ];
Upvotes: 2