Tcl传递args"按原样#34;过程

时间:2014-11-13 13:08:59

标签: list tcl proc args

我想发送命令

exp_send -i $sid -- "yes\r"

到一个将执行命令并检查错误的函数。 应该是:

catch {exp_send -i $sid -- "yes\r"}

其中:

[catch {$cmd [join $args]}

此代码中有什么问题:

package require Expect

proc ErrorDetector {cmd args} {

    global res

    if { [catch {$cmd [join $args]} results] } {
       puts "Connection Could not open for exp_send\n $results"
       return -level 0 0
     }

    puts sion.
}


global spawn_id
set sid [spawn cmd.exe]
exp_send {ssh root@10.64.88.240}


ErrorDetector exp_send -i $sid -- "yes\r"

comamnd:

$cmd [join $args]

未按以下方式运行:

$cmd [join $args]

2 个答案:

答案 0 :(得分:0)

使用

$cmd [join $args]

你传递的命令只是一个带有所有参数的字符串的参数。要将命令列表传递给命令,您需要输入字符串命令和参数,然后对其进行评估:

eval "$cmd [join $args]"

所以,结果命令是

[catch [eval "$cmd [join $args]"] results]

我认为这样可行。如果有问题,请告诉我。

我对我的系统没有期望,我无法用它进行测试。但Expect是tcl,所以我尝试修复tcl问题。与

proc ErrorDetector {cmd args} {

   global res
   if {[catch {eval "$cmd [join $args]"} results]} {

      puts "Connection Could not open for exp_send\n $results"
      return -level 0 0
   }

   puts sion.
}

proc test {a b c} {
    puts "a = $a - b = $b - c = $c"
}

ErrorDetector test 1 2 3

在这种情况下,输出为:

a = 1 - b = 2 - c = 3
sion.

这是正确的。用:

Connection Could not open for exp_send
 wrong # args: should be "test a b c"
sion.

这是正确的:我在没有参数的情况下调用test。

对于第二个问题:如果使用-level 0,则在错误后继续当前函数(不返回!)。如果使用-level 1,则完成当前函数,然后执行父函数中的第一行。

答案 1 :(得分:0)

如果你有一个最近版本的Tcl落后于Expect,你可以这样做:

$cmd {*}$args

否则,对于旧版本的Tcl(8.4及之前版本),正确的方法是:

eval [list $cmd] $args
# Paranoid version: eval [list $cmd] [lrange $args 0 end]
eval [linsert $args 0 $cmd]

以上所有内容都会准确地保留您作为程序参数提供的单词。 join的内容将;该命令特别适用于创建诸如人类可读事物列表之类的内容,以及用于处理旧式“数据库”记录(例如您在Unix密码数据库中找到的记录)。