如何在其他tcl脚本中运行tcl脚本?

如何在其他tcl脚本中运行tcl脚本?,tcl,Tcl,我有两个tcl脚本。我想在第一个脚本完成后运行第二个脚本。我该怎么做呢?取决于你的真正意思 一种方法是编写第三个(“主”)脚本 source /the/path/to/the/first.tcl source /the/path/to/the/second.tcl 另一种方法是将上面示例中对source的第二个调用添加到第一个脚本的底部 对第一种方法的修正:如果要执行的脚本与主脚本位于同一目录中,则可以使用source的惯用方法 set where [file dirname [info sc

我有两个tcl脚本。我想在第一个脚本完成后运行第二个脚本。我该怎么做呢?

取决于你的真正意思

一种方法是编写第三个(“主”)脚本

source /the/path/to/the/first.tcl
source /the/path/to/the/second.tcl
另一种方法是将上面示例中对
source
的第二个调用添加到第一个脚本的底部

对第一种方法的修正:如果要执行的脚本与主脚本位于同一目录中,则可以使用
source
的惯用方法

set where [file dirname [info script]]
source [file join $where first.tcl]
source [file join $where second.tcl]

无论当前流程的目录是什么,项目目录位于何处,这种寻源方式都会起作用。

您只需要使用源代码来运行第二个脚本

source "/tmp/whatever.tcl"

虽然这通常是一个正确的答案,但因为这个问题没有精确地表述出来,所以有很多方法可以实现从Tcl内部运行Tcl代码的目标。 我想详细介绍一下,因为理解代码的执行是理解Tcl本身的一个重要方面

源代码
source
命令不应与以经典方式执行脚本相混淆,我认为线程启动程序已经提出了这一要求

源命令类似于c/perl/php中的“include”命令。 另一方面,java或python等语言只有“导入”机制

不同之处在于,这些语言创建了可用包的内部数据库,这些包链接到相应的源/二进制/字节码文件。通过编写导入语句,可以加载链接的源代码、字节码或二进制文件。这允许在不编写额外代码的情况下进行更深入的依赖关系管理。 在Tcl中,这可以通过名称空间和
包require
命令实现。 例如:

假设您有这个source.tcl:

proc foo {bar} {puts "baz"}
set BAM "BOO"
现在,你有了你称之为“大师”的剧本。我称之为“主”。其内容包括:

set BAM {my important data}
source source.tcl
#also the function foo can now be used because the source reads the whole script
foo {wuz}
set BAM
#will output "BOO"
exec
命令 如果您可以承受启动一个全新解释器实例的额外开销,您还可以:

set BAM {my important data}
exec tclsh source.tcl
#The variable BAM will not be modified. You can not use the function foo.
eval
命令 命令
eval
可以计算字符串或列表(在Tcl中,一切都是字符串),就像它是编程代码一样。 您必须将完整的源文件加载到字符串中。然后使用
eval
,在单独的范围内评估代码,以避免覆盖主源文件中的内容

set fp [open "somefile" r]
set code_string [read $fp]
close $fp
eval $code_string

我能找到的最简单的工作示例:

thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ tclsh main.tcl 
hello world
7
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ cat main.tcl 
lappend auto_path /home/thufir/NetBeansProjects/spawnTelnet/telnet/api

package require weather 1.0



tutstack::hello

set A 3
set B 4

puts [tutstack::sum $A $B]


#puts [tutstack::hello "fred"]



thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ cat api/weather.tcl 
package provide weather  1.0
package require Tcl      8.5

namespace eval ::tutstack {
}

proc ::tutstack::hello {} {
    puts "hello world"
}


proc ::tutstack::sum {arg1 arg2} {
    set x [expr {$arg1 + $arg2}];
    return $x
}

proc ::tutstack::helloWorld {arg1} {
    return "hello plus arg"
}
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ cat api/pkgIndex.tcl 
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded weather 1.0 [list source [file join $dir weather.tcl]]
thufir@dur:~/NetBeansProjects/spawnTelnet/telnet$ 

评估一段代码的另外两个主要途径:子解释器和线程包。还有
namespace eval
uplevel
(但它们与
eval
非常相似,只是它们改变了它们在其中计算的确切上下文)以及除此之外的许多其他命令。