【发布时间】:2012-03-05 17:10:08
【问题描述】:
我有两个 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 script]]
source [file join $where first.tcl]
source [file join $where second.tcl]
无论当前进程的目录是什么以及项目目录位于何处,这种方式都可以进行采购。
【讨论】:
虽然这通常是一个正确的答案,但由于这个问题没有精确地表述,有很多方法可以实现从 Tcl 中运行 Tcl 代码的目标。 我想详细介绍一下,因为理解代码的执行是理解 Tcl 本身的一个重点。
source
source 命令不应该与以经典方式执行脚本混淆,我认为线程启动器已经问过了。
source 命令类似于 c/perl/php 中的“include”命令。 另一方面,像 java 或 python 这样的语言只有“导入”机制。
不同之处在于,这些语言创建了一个可用包的内部数据库,这些包链接到相应的源/二进制/字节码文件。通过编写导入语句,加载链接的源代码或字节码或二进制文件。这允许在不编写额外代码的情况下进行更深入的依赖管理。
在 Tcl 中,这可以通过命名空间和package 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
【讨论】:
namespace eval 和 uplevel(但它们与 eval 非常相似,只是它们改变了它们在其中评估的确切上下文)以及可以说除此之外的许多其他命令。
您只需要使用源代码来运行第二个脚本。
source "/tmp/whatever.tcl"
【讨论】:
我能找到的最简单的工作示例:
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$
【讨论】: