Task()正在转义引号

时间:2016-11-06 09:23:19

标签: swift macos shell

使用Process()创建网络监视任务。

我正在尝试向Task发送一个带引号的参数(要监视的进程名称)。这需要单引号,因为它可以有空格。 (参见 task.arguments?.append(" -p'(procName!)'")下面)

        task = Process()
        pipe = Pipe()
        task.launchPath = "/usr/bin/nettop"

        task.arguments = ["-j time,interface,state,bytes_in,bytes_out","-k rx_dupe,rx_ooo,re-tx,rtt_avg,rcvsize,tx_win,tc_class,tc_mgt,cc_algo,P,C,R,W","-n","-L 0"]
        var procName = currentSelection?.procname
        if(procName != nil && procName != "") {
            task.arguments?.append("-p '\(procName!)'")
        }
        task.standardOutput = pipe
        task.launch()

根据文档,由于没有发生shell扩展,因此不需要引用

https://developer.apple.com/reference/foundation/process/1408983-arguments

具体地

NSTask对象在将参数中的路径和字符串转换为适当的C样式字符串(使用fileSystemRepresentation),然后通过argv []将它们传递给任务。参数中的字符串不会进行shell扩展,因此您不需要进行特殊引用,并且不会解析shell变量(如$ PWD)。

然而,它似乎是自动转义它们并将该转义版本作为文字发送到操作系统。调试器将它们显示为已转义,无论我是否手动转义它们,以便在此处了解其状态。我无法获得nettop的完整命令行以显示在top,htop或ps -f中,但实际上,当我将procName添加到任务参数列表时,命令不会获得除正常nettop标头之外的任何数据。这表明nettop正在运行,它只是没有找到它的嗅探过程。

所以,问题是:我如何将一个引用的参数(例如' Google Chrome')作为参数发送给Process()?

1 个答案:

答案 0 :(得分:1)

进程名称必须作为单个参数传递,不带任何引号:

var procName = currentSelection?.procname
if (procName != nil && procName != "") {
    task.arguments?.append(contentsOf: ["-p", procName! ])
}

或者更好(避免任何强制解开):

var arguments = ["-j time,interface,state,bytes_in,bytes_out", ...]
if let procName = currentSelection?.procname, !procName.isEmpty {
    arguments += ["-p", procName ]
}
task.arguments = arguments