【发布时间】:2015-03-19 01:44:10
【问题描述】:
如果有人想从 Bash 调用外部程序(作为 Bash 参数传递)并传递命令行选项(也作为 Bash 参数传递),那么解决方案非常简单:
TCL_SCRIPT="$1"
shift
TCL_SCRIPT_ARGUMENTS="$@"
expect -f "$TCL_SCRIPT" "$TCL_SCRIPT_ARGUMENTS" 2>&1
在 TCL/Expect 中是否有类似的可能?
编辑: 到目前为止,我已经有了这个 hack(在 cmets 中有 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
【问题讨论】:
-
该脚本,如所写,不适用于带空格的参数。只是为了记录。您不会将
$@存储在变量中,您只需在需要的地方使用它。除此之外,我不确定我是否理解这个问题。您是否在询问如何通过expect将参数传递给命令spawned?你的expect脚本是什么样的? -
如果你使用的是 tcl8.6,你可以使用
exec {*}$::argv 2>@1。否则,总是有eval exec $::argv 2>@1。 -
我的意思是,如果你有一个带空格的参数,当你把它塞进一个字符串时,你将失去使
$@安全的单词扩展行为。请尝试以下操作以了解我的意思。c() { printf 'argc: %s\n' "$#"; printf '$@: %s\n' "$@"; TCL_SCRIPT_ARGUMENTS="$@"; printf 'TCL_SCRIPT_ARGUMENTS: %s\n' "$TCL_SCRIPT_ARGUMENTS"; }; c foo 'bar baz' quux(将set -x添加到该函数的开头也可以更清楚地看到它。) -
printf反复使用该格式来消耗其所有输入。因此,当您说printf '%s\n' a b c时,它需要使用%s\n格式三次才能使用它。大多数命令都不是这样工作的。 -
@WakanTanka
{*}$var是tcl等价于"$@":它将扩展列表,以便每个列表元素都是正确引用的参数。所以,假设我们有set lst {item1 "item 2" item3},MyProc {*}$lst相当于MyProc item1 {item 2} item3
标签: bash arguments command-line-arguments expect argument-passing