TCL exec 变量 arg 字符串以 <、> 或 | 等特殊字符开头

TCL exec with variable arg string starting with specials characters like <, >, or |

我正在尝试从 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>"] # '

这与 类似,但 < 抛弃了那里的解决方案

此外,也许值得注意

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) 额外的空格或字符足以回避问题(但如何将它们与用户 provided/parsed 变量一起使用)

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>"

我不太了解您要做什么,但经过一些搜索,我发现了 this post (and since that didn't quite work...) and this post。一起来看,好像是下面的作品:

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

在第一个 link 上引用科林的话:

Tcl's exec does not invoke bash or do this conversion by itself. You can make it work by explicitly calling bash from Tcl

解决这个问题的一种方法(从@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