我正在从TCL脚本中启动多个tclsh来模拟多线程。但是这些电话都失败了。
我已将问题简化为TCL proc启动tclsh的测试。
proc launch_tcl {} {
set cmd "tclsh script.tcl"
set pid [ eval $cmd & ]
}
这会产生:invalid command name "tclsh"
我可以在TCL提示符上给出以下行,它们可以正常工作。
set cmd "tclsh script.tcl"
set pid [ eval $cmd & ]
我已尝试使用tclsh以及二进制文件的完整路径以及相同的失败。
为什么相同的命令在proc中失败?
谢谢, 格特
答案 0 :(得分:2)
虽然Tcl语法看起来与shell语法更相关,如bash或tcsh,但tcl实际上与Perl或PHP或Ruby更紧密相关。 Tcl只解释tcl代码,因此只输入另一个可执行文件的名称就不会启动该可执行文件*。
就像Perl或Ruby(或者实际上是C和C ++)一样,tcl确实具有启动可执行文件的机制。为此,您需要exec
命令:
exec tclsh script.tcl
与产生外部二进制文件的命令接受字符串的其他语言不同,tcl的exec与C或javascript的关系更密切,因为它接受结构化数据。如果您尝试这样做:
exec "tclsh script.tcl"
您会收到错误抱怨" tclsh script.tcl"不存在。它将查找名为" tclsh script.tcl"的可执行文件。 (因为unix从一开始就允许程序名包含空格)。相反,您需要分别传递程序名称和每个单独的参数。同样,如果你尝试过:
exec tclsh "arg1 arg2"
exec命令将执行tclsh并传递字符串" arg1 arg2" 作为第一个参数。
有关详细信息,请参阅exec文档:https://www.tcl.tk/man/tcl/TclCmd/exec.htm
不要将命令存储在字符串中。在tcl中没有真正安全的方法来分隔字符串中的参数。而是将您的命令组成一个列表,然后在调用exec时使用{*}
运算符展开列表:
set cmd [list tclsh script.tcl]
exec {*}$cmd
*注意:可能存在混淆,因为在交互模式下,如果您输入可执行文件,则确实会启动可执行文件。但这只是交互模式的一个特征。