无法从tclsh启动tclsh

时间:2017-05-18 21:42:40

标签: tcl

我正在从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中失败?

谢谢, 格特

1 个答案:

答案 0 :(得分:2)

虽然Tcl语法看起来与shell语法更相关,如bash或tcsh,但tcl实际上与Perl或PHP或Ruby更紧密相关。 Tcl只解释tcl代码,因此只输入另一个可执行文件的名称就不会启动该可执行文件*。

就像Perl或Ruby(或者实际上是C和C ++)一样,tcl确实具有启动可执行文件的机制。为此,您需要exec命令:

exec tclsh script.tcl

关于exec如何工作的警告:

与产生外部二进制文件的命令接受字符串的其他语言不同,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
  

*注意:可能存在混淆,因为在交互模式下,如果您输入可执行文件,则确实会启动可执行文件。但这只是交互模式的一个特征。