列表中有特殊字符的 TCL exec

TCL exec with special characters in list

有一个 tcl 程序用于执行存储在 tcl 列表中的命令。 例如:

catch { exec $list}

列表类似于:

--option1 op1 --option2 op2 --option3 op3 ...

其中一个选项是正则表达式,如下所示:

(.*[/\])?(sh|bash)(\.exe)?

替换后执行选项看起来像:

{(.*[/\])?(sh|bash)(\.exe)?}

但我需要的是:

"(.*[/\])?(sh|bash)(\.exe)?"

遇到这种情况我该怎么办?

当列表转换为字符串时,它会转换为规范形式,该形式将转换回相同的列表。

您看到的是用于确保规范格式正确转换回的引号字符。

所以这个值是正确的。

exec $list 只将一个参数传递给 execexec 将一系列单词作为参数,而不是包含单词的列表。

exec命令应该是:

catch { exec {*}$list }

{*} 语法将列表转换为其组成词。

在老版本的tcl中,必须使用eval语句:

catch { eval exec $list }

参考文献:exec, eval, {*} (section 5 of Tcl)

  1. exec 将作为子进程执行 commnad

  2. 见示例:

    有效:

    执行 ps 辅助 | grep tclsh

    不工作:

    exec "ps aux | grep tclsh"

    exec [list ps aux | grep tclsh]

    但工作正常:

    eval exec "ps aux | grep tclsh"

    eval exec [list ps aux | grep tclsh]

所以我们在执行创建命令(exec ps aux | grep tclsh)并调用它之前进行了评估。所以 eval 不关心类型。

  1. 对于选项的当前情况:exec someExecutable --option1 op1 --option2 op2 --option3 (.*[/\])?(sh|bash)(\.exe)?

我会推荐这样的解决方案:

set op3 {"(.*[/\])?(sh|bash)(\.exe)?"}
lappend cmd  [someExecutable --option1 op1 --option2 op2 --option3 $op3]
set cmd [join $cmd]
eval exec $cmd

其中 [join $cmd] 从列表创建字符串 - 但没有任何 { }