Passing arguments from command line into a tcl script
Asked Answered
B

4

9

I have a TCL script that has many parameters defined as arguments. I intend to create a job file where I can execute the .tcl script with different combinations of the parameters without manual intervention.

What I mean is the following:

Job File (run.sh):

./main.tcl arg1 arg2 arg3 arg4 
./main.tcl arg1 arg3 arg5

Now I want to be able to pass the command line argument array "argv" for each run mentioned in run.sh as an array into the main.tcl script so that the options are set accordingly within the script prior to execution.

Is there a way to link the .sh script and the .tcl script?

Bollix answered 24/6, 2014 at 0:1 Comment(4)
Inside your shell script you can refer to the list of all arguments as $@. So just say main.tcl $@Statued
@JohnC - thanks for the reply! ok, so if i do ./main.tcl $@ inside my run.sh, then how can i retrieve the arguments inside of main.tcl? using argv?Bollix
I think the answer below covers that for you.Statued
This explains it and also gives you a concrete example.Cydnus
P
10

Per online document here:

The method by which numbers can be passed into, and used by a script, is as follows.

argc argv argv0

All Tcl scripts have access to three predefined variables. $argc - number items of arguments passed to a script. $argv - list of the arguments. $argv0 - name of the script.

To use the arguments, the script could be re-written as follows.

if { $argc != 2 } {
    puts "The add.tcl script requires two numbers to be inputed."
    puts "For example, tclsh add.tcl 2 5".
    puts "Please try again."
} else {
    puts [expr [lindex $argv 0] + [lindex $argv 1]]
    }
Psych answered 24/6, 2014 at 0:21 Comment(4)
This link is dead now.Electrolyze
Note that written like that, it amounts to a command injection vulnerability, try with tclsh that-script '[exec sh -c {id>/dev/tty; echo 1}]' 2 for instance. Better with puts [expr {[lindex $argv 0] + [lindex $argv 1]}].Cephalization
link is fundza.com/tcl/script_shell/arguments/index.htmlBunsen
To improve the example, it would be helpful to have the command that exits the script with an error code if the arguments are not found.Cavalry
T
2

For demonstrating how to pass arguments from the command line into a TCL script:

Create a text file named args.tcl that contains the following commands:

# If no command line arguments are passed perform no actions
if {$argc > 0} {
# argv0 conatins the filename of the script
puts "The name of the script is: $argv0"
# argc contains the count of the arguments passed
puts "Total count of arguments passed is: $argc"
# argv contains a list of the arguments
puts "The arguments passed are: $argv"
# Using the List Index of argv print a specific argument
puts "The first argument passed was [lindex $argv 0]"
}

After you have created the file invoke the script with the following command line:

> Tclsh85 args.Tcl ONE 2 3
The name of the script is: args.Tcl
Total count of arguments passed is: 3
The arguments passed are: ONE 2 3
The first argument passed was ONE
>

Reference: Tcl/Tk 8.5 Programming Cookbook

Tokharian answered 31/12, 2021 at 23:27 Comment(0)
R
1

In addition to the above answer, I found the following helpful:

For running within QuestaSim/ModelSim/Quartus I followed the following resource: http://www.alteraforum.com/forum/showthread.php?t=3034

Typically we can run .tcl scripts with the source command, but this doesn't inherently process arguments like base .tcl scripts can use normally. So by using a process, you can achieve the same thing.

Revisionist answered 17/10, 2016 at 22:30 Comment(0)
B
1

I find that it's often easiest to parse arguments (the useful ones of which are always passed as a list in the global argv variable, with the length of that list in the global argc variable; C programmers will recognise the names) like this:

switch $argc {
    2 {
        # Split the arguments and set the default for the optional
        lassign $argv firstArg secondArg
        set thirdArg "default value"
    }
    3 {
        # Split all the arguments
        lassign $argv firstArg secondArg thirdArg
    }
    default {
        # Oh no! Give the user an error message and stop
        error "wrong # args: should be \"$argv0 firstArg secondArg ?thirdArg?\""
    }
}

The global argv0 is the name of the script. Properly it would be one of the arguments in argv/argc (along with potentially the name of the Tcl interpreter) but almost nobody usually uses it in the same way so it is split out for you. As I said, the useful arguments are in argv.

You can also use any other list handling command with argv; foreach works great for a sequence of filenames, for example.

Beech answered 31/5, 2023 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.