无法从tclsh启动tclsh

无法从tclsh启动tclsh,tcl,Tcl,我正在从TCL脚本内部启动多个tclsh以模拟多线程。然而,所有的调用都失败了 我已经将问题简化为一个测试,其中TCL进程启动tclsh proc launch_tcl {} { set cmd "tclsh script.tcl" set pid [ eval $cmd & ] } 这将产生:无效的命令名“tclsh” 我可以在TCL提示符下给出以下几行代码,它们工作得很好 set cmd "tclsh script.tcl" set pid [ ev

我正在从TCL脚本内部启动多个tclsh以模拟多线程。然而,所有的调用都失败了

我已经将问题简化为一个测试,其中TCL进程启动tclsh

proc launch_tcl {} {
    set cmd "tclsh script.tcl"
    set pid [ eval $cmd & ]
}
这将产生:
无效的命令名“tclsh”

我可以在TCL提示符下给出以下几行代码,它们工作得很好

    set cmd "tclsh script.tcl"
    set pid [ eval $cmd & ]
我也尝试过使用二进制文件的完整路径进行tclsh,但同样失败

为什么相同的命令在进程内失败

谢谢,
Gert

虽然Tcl语法看起来更像bash或tcsh之类的shell语法,但实际上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的文档:

如果您有一个字符串中的命令,该怎么办? 不要以字符串形式存储命令。在tcl中,没有真正安全的方法来分隔字符串中的参数。而是将命令组合为列表,然后在调用exec时使用
{*}
操作符展开列表:

set cmd [list tclsh script.tcl]
exec {*}$cmd
*注意:这可能会引起混淆,因为在交互模式下,如果您键入tcl,它确实会启动可执行文件。但这只是互动模式的一个特点


虽然Tcl语法看起来更像bash或tcsh之类的shell语法,但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的文档:

如果您有一个字符串中的命令,该怎么办? 不要以字符串形式存储命令。在tcl中,没有真正安全的方法来分隔字符串中的参数。而是将命令组合为列表,然后在调用exec时使用
{*}
操作符展开列表:

set cmd [list tclsh script.tcl]
exec {*}$cmd
*注意:这可能会引起混淆,因为在交互模式下,如果您键入tcl,它确实会启动可执行文件。但这只是互动模式的一个特点