带变量arg字符串的TCL exec,以特殊字符(如<,>或|

时间:2019-03-05 17:15:14

标签: escaping tcl

我正在尝试从tcl exec,传递一个可以以<,(或|>)开头的变量作为参数。 tcl似乎认为我想将文件的输入定向到命令,而不是使用文字尖括号。

set cmd "<hi>"
exec echo $cmd                # couldn't read file "hi>"
eval exec [list echo $cmd]    # couldn't execute "echo <hi>"
eval exec {*}[list echo $cmd] # couldn't read file "hi>"

在对字符串进行硬编码时,我什至无法获得预期的<hi>

eval exec {*}{"echo" <hi>}   # couldn't read file "hi>"
exec echo {"<hi>"}           # "<hi>"  # but I don't want quotes
exec echo {\<hi>}            # \<hi>   # nor a leading \
exec echo {<hi>}             # couldn't read file "hi>"
exec echo {*}[list "<hi>"]   # '
eval exec echo [list "<hi>"] # '

这类似于TCL exec with special characters in list,但<抛弃了那里的解决方案

另外,也许值得注意

1)具有额外的参数允许|通过,但不允许<

eval exec {*}[list echo {|foo bar} ] # |foo bar  # WORKS? WHAT?
eval exec {*}[list echo {|foo} ]     # illegal use of | or |& in command
eval exec {*}[list echo {<foo bar} ] # couldn't read file "foo"

2)多余的空格或字符足以解决问题(但如何将其与用户提供/解析的变量一起使用)

exec echo { <hi>}               #  <hi>    # with leading space
exec echo { |hi}                #  |hi     # with leading space
exec echo [list " " $cmd]       # { } <hi> # not useful
exec echo {*}[list " " $cmd]    #            couldn't read file "hi>"
exec echo [join [list "" $cmd]] #  <hi>    # leading space

exec echo [string trim [join [list "" $cmd]]] # couldn't read file "hi>"

2 个答案:

答案 0 :(得分:1)

我不太了解您要做什么,但是经过一番搜寻,我发现了this post(并且由于这样做不起作用...)和this post。在一起,似乎是以下作品:

% exec bash -c {echo "<hi>"}
<hi>

在第一个链接上引用科林:

  

Tcl的exec本身不会调用bash或执行此转换。您可以通过从Tcl显式调用bash来使其工作

答案 1 :(得分:1)

解决此问题的一种方法(从@jerry那里窃取了一点)是将命令写入临时文件并使用shell运行它

   set f [file tempfile fn "/tmp/cmd"]
   # open $fn w # unnecessary
   puts $f $cmd
   close $f
   set shcmd "echo \"`cat $fn`\""
   exec sh -c $shcmd 
   file delete $fn