简体   繁体   English

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

[英]How to run tcl script inside other tcl script?

I have two tcl scripts.我有两个 tcl 脚本。 I want to run the second script when the first finished.我想在第一个脚本完成后运行第二个脚本。 How can I do it?我该怎么做?

Depends on what do you really mean.取决于你的真正意思。

One way is to write a third ("master") script which would do一种方法是编写第三个(“主”)脚本

source /the/path/to/the/first.tcl
source /the/path/to/the/second.tcl

Another way is to just add the second call to source from the above example to the bottom of the first script.另一种方法是将上述示例中对source的第二个调用添加到第一个脚本的底部。

Amendment to the first approach: if the scripts to be executed are located in the same directory as the master script, an idiomatic way to source them is修正案第一种方法:如果要执行的脚本位于同一目录中的主脚本,一个惯用的方式来source他们是

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

This way sourcing will work no matter what the current process's directory is and where the project directory is located.无论当前流程的目录是什么以及项目目录位于何处,这种方式的采购都将起作用。

While this is generally a correct answer, because the question was not precisely formulated there are tons of ways to achieve the goal of running Tcl code from within Tcl.虽然这通常是一个正确的答案,因为问题没有被精确地表述出来,有很多方法可以实现从 Tcl 中运行 Tcl 代码的目标。 I want to get into this in detail because understanding the execution of code is one major point in understanding Tcl itself.我想详细讨论这个,因为理解代码的执行是理解 Tcl 本身的一个重点。

There is source source

The source command should not be confound with executing scripts in a classical way, what I think the thread starter has asked. source命令不应该与以经典方式执行脚本混淆,我认为线程启动器已经提出了这一要求。

The source command is like the "include" command in c/perl/php. source 命令类似于 c/perl/php 中的“include”命令。 Languages like java or python on the other hand only have "import" mechanisms.另一方面,像 java 或 python 这样的语言只有“导入”机制。

The difference is that those languages create a internal database of available packages, who are linked to the corresponding source/binary/bytecode files.不同之处在于这些语言创建了可用包的内部数据库,这些包链接到相应的源/二进制/字节码文件。 By writing a import statement, linked source or bytecode or binary files are loaded.通过编写导入语句,链接的源或字节码或二进制文件被加载。 This allows more in-depth dependency management without writing additional code.这允许更深入的依赖管理,而无需编写额外的代码。 In Tcl this can be achieved with namespaces and the package require command.在 Tcl 中,这可以通过命名空间和package require命令来实现。 Example:例子:

Suppose you have this source.tcl:假设你有这个 source.tcl:

proc foo {bar} {puts "baz"}
set BAM "BOO"

Now, you have your "master" script like you call it.现在,您拥有了您所说的“主”脚本。 I call it "main".我称之为“主要”。 It has the content:它有以下内容:

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"

The exec command exec命令

If you can live with additional overhead of starting a whole new interpreter instance you could also do:如果您可以忍受启动全新解释器实例的额外开销,您还可以执行以下操作:

set BAM {my important data}
exec tclsh source.tcl
#The variable BAM will not be modified. You can not use the function foo.

The eval command eval命令

The command eval can evaluate a string or a list (in Tcl everything is a string) like it would be programmed code.命令eval可以像编程代码一样评估字符串或列表(在 Tcl 中,一切都是字符串)。 You would have to load the complete source file to a string.您必须将完整的源文件加载到字符串中。 And then use eval , to evaluate the code within a separate scope, to not overwrite stuff in your main source file.然后使用eval来评估单独范围内的代码,不要覆盖主源文件中的内容。

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

您只需要使用 source 来运行第二个脚本。

source "/tmp/whatever.tcl"

Simplest possible working example I could find:我能找到的最简单的工作示例:

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$ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM