How to run tcl script inside other tcl script?
Asked Answered
E

4

18

I have two tcl scripts. I want to run the second script when the first finished. How can I do it?

Elenaelenchus answered 14/2, 2012 at 10:13 Comment(0)
C
21

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.

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

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.

Census answered 14/2, 2012 at 11:18 Comment(0)
A
10

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. I want to get into this in detail because understanding the execution of code is one major point in understanding Tcl itself.

There is source

The source command should not be confound with executing scripts in a classical way, what I think the thread starter has asked.

The source command is like the "include" command in c/perl/php. Languages like java or python on the other hand only have "import" mechanisms.

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. Example:

Suppose you have this 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

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

The command eval can evaluate a string or a list (in Tcl everything is a string) like it would be programmed code. 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.

set fp [open "somefile" r]
set code_string [read $fp]
close $fp
eval $code_string
Allhallows answered 15/1, 2018 at 15:48 Comment(1)
Two other major routes for evaluating a piece of code: child interpreters, and the thread package. And then there's namespace eval and uplevel (but they're very much like eval except in that they change what exact context they evaluate within) and arguably many other commands besides.Virginia
W
5

You just need to use source to run the 2nd script.

source "/tmp/whatever.tcl"
Wiedmann answered 14/2, 2012 at 11:19 Comment(0)
A
0

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$ 
Agace answered 8/5, 2020 at 0:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.