【问题标题】:Fail to launch tclsh from tclsh无法从 tclsh 启动 tclsh
【发布时间】:2017-05-18 21:42:39
【问题描述】:

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

谢谢, 格特

【问题讨论】:

    标签: tcl


    【解决方案1】:

    虽然 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 的文档:https://www.tcl.tk/man/tcl/TclCmd/exec.htm

    如果字符串中有命令怎么办?

    不要将命令存储在字符串中。在 tcl 中没有真正安全的方法来分隔字符串中的参数。而是将您的命令组合成一个列表,然后在您调用 exec 时使用 {*} 运算符来展开列表:

    set cmd [list tclsh script.tcl]
    exec {*}$cmd
    

    *注意:这可能会造成混淆,因为在交互模式下,如果你键入它,tcl 确实会启动可执行文件。但这只是交互模式的一个功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-19
      相关资源
      最近更新 更多