Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCL/Expect equivalent of Bash $@ or how to pass arguments to spawned process in TCL/Expect

If somebody wants to call external program (which was passed as a Bash argument) from Bash and also pass it command line options (which were also passed as a Bash arguments) the solution is fairy simple:

TCL_SCRIPT="$1"
shift
TCL_SCRIPT_ARGUMENTS="$@"
expect -f "$TCL_SCRIPT" "$TCL_SCRIPT_ARGUMENTS" 2>&1

Is something similar possible in TCL/Expect ?

EDIT: So far I've come with this hack (there are Bash equivalents in comments), which seems that it is working. Can somebody explain lshift procedure?

# http://wiki.tcl.tk/918#pagetocc7993a2b
proc lshift {inputlist} {
  upvar $inputlist argv
  set arg  [lindex $argv 0]
  #set argv [lrange $argv 1 end] ;# below is much faster - lreplace can make use of unshared Tcl_Obj to avoid alloc'ing the result
  set argv [lreplace $argv[set argv {}] 0 0]
  return $arg
}

# BASH: TCL_SCRIPT="$1"
set script [lindex $argv 0]

# BASH: shift
lshift argv

# BASH: TCL_SCRIPT_ARGUMENTS="$@"
set arguments $argv
like image 805
Wakan Tanka Avatar asked Jan 20 '15 17:01

Wakan Tanka


People also ask

What is expect in Tcl?

Expect is an extension to the Tcl scripting language written by Don Libes. The program automates interactions with programs that expose a text terminal interface. Expect, originally written in 1990 for the Unix platform, has since become available for Microsoft Windows and other systems.

How do you read command line arguments in Expect script?

Normally you would read the command line arguments as shown below. $ cat print_cmdline_args. exp #!/usr/bin/expect puts 'argv0 : [lindex $argv 0]'; puts 'argv1 : [lindex $argv 1]';

What is args in Tcl?

Tcl Built-In Commands Args specifies the formal arguments to the procedure. It consists of a list, possibly empty, each of whose elements specifies one argument. Each argument specifier is also a list with either one or two fields.


1 Answers

To literally translate your example

set program [lindex $argv 0]
set arguments [lrange $argv 1 end]
spawn $program {*}$arguments

{*} is Tcl's "list expansion" syntax (rule 5 of Tcl's 12 rules of syntax). It splits a list into its element in the current command.

If $argv is foo bar baz, then

spawn [lindex $argv 0] [lrange $argv 1 end]

will invoke foo with 1 argument: "bar baz"

spawn [lindex $argv 0] {*}[lrange $argv 1 end]

will invoke foo with 2 arguments: "bar" and "baz"


Tangentially, I would code your lshift proc like this:

proc lshift {varname} {      
    upvar 1 $varname var
    set var [lassign $var first]
    return $first
}

Then:

expect1.6> set argv {foo bar baz}
foo bar baz
expect1.7> set script [lshift argv]
foo
expect1.8> set script
foo
expect1.9> set argv
bar baz
like image 69
glenn jackman Avatar answered Dec 29 '22 05:12

glenn jackman