TCL / Expect相当于Bash $ @或如何将参数传递给TCL / Expect中的生成进程

时间:2015-01-20 17:51:27

标签: bash arguments command-line-arguments expect argument-passing

如果有人想从Bash调用外部程序(作为Bash参数传递)并传递命令行选项(也作为Bash参数传递),解决方案很简单:

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

在TCL / Expect中有类似的可能吗?

编辑: 到目前为止,我已经接受了这个黑客攻击(评论中有Bash等价物),似乎它正在运行。有人可以解释lshift程序吗?

# 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

2 个答案:

答案 0 :(得分:11)

直译你的例子

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

{*}是Tcl"列表扩展"语法(Tcl's 12 rules of syntax的规则5)。它将列表拆分为当前命令中的元素。

如果$argvfoo bar baz,那么

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

将使用 1参数调用foo"bar baz"

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

将使用 2个参数foo"bar"

调用"baz"

切线,我会像这样编码你的lshift proc:

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

然后:

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

答案 1 :(得分:0)

我发现@glenn jackman的答案对于较旧的TCL是不够的,即8.5之前的版本,特别是对于运行Expect scipts的旧版Unicies。我去搜索并发现了一个注释,“lassign”函数在8.5之前的TCL中不可用:(http://wiki.tcl.tk/1530,在“在Vcl之前的Tcl中,foreach用于实现lassign的功能:”)中。

在同一页上,在“示例:Perl-ish shift”标题下,有一个声明说“另一方面,Hemang Lavana观察到TclXers已经有lvarpop :: argv,这是shift的确切同义词。” )重定向到此页面的“lvarpop”:http://wiki.tcl.tk/1965

该页面末尾的代码是简化版本,为方便起见,此处转载:

proc lvarpop {upVar {index 0}} {
    upvar 1 $upVar list
    if {![info exists list]} { return "-1" }
    set top [lindex $list $index]
    set list [lreplace $list $index $index]
    return $top
}

在我的测试中,这适用于零到几乎无数个以空格分隔的算法。对于像我这样的TCL挑战者来说,这是天赐之物。