【问题标题】:Cannot Pass Argument to /bin/sh无法将参数传递给 /bin/sh
【发布时间】:2014-04-12 21:36:39
【问题描述】:

我正在为我的一个可可应用程序编写命令行助手。这个帮助工具应该使用NSTask 执行一个shell ( /bin/sh ) 实例。众所周知,可以利用-c 执行sh,您可以传递一个或多个命令作为要执行的参数。

例如运行/bin/sh -c "networksetup -setwebproxystate Wi-Fi on"

执行networksetup -setwebproxystate Wi-Fi on

现在,问题来了:

当我将启动路径设置为sh[task setLaunchPath:@"/bin/sh"]),然后设置参数如下:

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];

我看到 -c 参数以某种方式被跳过,因为我收到以下错误:

/bin/sh: "networksetup -setwebproxystate Wi-Fi on": command not found

那是因为"networksetup -setwebproxystate Wi-Fi on" 是直接执行的,而不是sh -c 之后的参数。

我知道我无法以最清晰的方式解释,但希望我能表达我的意思。

我尝试了几乎所有想到的东西,但我被困住了。任何建议都非常感谢。

【问题讨论】:

    标签: cocoa shell unix arguments nstask


    【解决方案1】:

    问题在于您指定命令字符串的方式非常复杂。 NSTask 不需要在参数周围加上引号。您最终会得到包含以下内容的参数:

    [0] ==> -c
    
    [1] ==> "networksetup -setwebproxystate Wi-Fi on"
    

    注意双引号。 为什么不直接使用

     arguments = [NSArray arrayWithObjects:
        @"-c",
        @"networksetup -setwebproxystate Wi-Fi on",
        nil ];
    

    【讨论】:

    • NSTask 不需要双引号,sh -c 需要。我首先有很多问题要在参数中传递",因为当我像\" 一样传递它时它被忽略了,但是在解决它之前传递另一个\`,现在我正在处理这个!尝试使用sh -c 执行命令,您会注意到我所说的。 (例如,您可以组合类似 `sh -c "firstCommand && secondCommand" 这样的命令,因此引号的存在是必要的);)
    • 顺便说一下,我写cmd = ... 的原因是,cmd 是从cin>> 接收的值设置的,所以这并不像听起来那么容易传递参数:D
    • 不,Unkn0wn,'sh -c' not 本身是否需要双引号。您正在输入的命令行处理器会执行此操作。 'sh -c' 需要的是一个单一参数,它是要解析和执行的整个命令。如果该命令需要自己的引号,那很好。而且我不明白为什么你需要这么多反斜杠 - 我怀疑你可能会将日志机制显示的内容与变量中实际显示的内容混淆......
    【解决方案2】:

    当在 shell 提示符下输入命令时,双引号用于将字符串作为 single 参数传递,否则它将作为多个参数传递。当使用NSTask(或exec 系列中的函数/系统调用)时,您单独传递每个参数,shell 不需要解析命令行,因此不需要双引号。以下片段:

    NSTask *task = [NSTask new];
    
    [task setLaunchPath:@"/bin/sh"];
    
    [task setArguments:@[@"-c", @"networksetup -setwebproxystate Wi-Fi on"]];
    
    [task launch];
    

    会做你想做的任务。这两个参数使用文字数组表达式传递,每个参数只是一个字符串,可能包含空格等。

    HTH

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 2015-11-11
      • 2020-05-15
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多