【问题标题】:tcl script not running properlytcl 脚本运行不正常
【发布时间】:2015-11-18 18:00:20
【问题描述】:

我正在使用 tcl 脚本打开与 linux 机器的 ssh 连接并打开虚拟交换机应用程序。在交换机 CLI 中,我添加了 >1000 个 IP 路由。

我以 = ./script_name.tcl 而不是通过 tclsh 运行脚本,因为这往往会给我一些错误。

问题在于 tcl 如何解释 tcl 脚本中的 while 循环。 我的 while 循环 -

sleep 1

set i 1
while {$i < 3 } {
    set j 2
    expect "*#"
    while {$j < 255} {
        send "ip route 2.2.$i.$j 255.255.255.255 4.4.4.1\r"
        incr j
    }
    incr i
}

sleep 1
expect "*#"

set k 1
while {$k < 3 } {
    set l 2
    expect "*#"
    while {$l < 255} {
        send "ip route 1.1.$k.$l 255.255.255.255 1.1.1.5\r"
        incr l
    }
    incr k
}

我使用 2 个 while 循环,每个循环添加约 500 条路线,因此总数应超过 1000 条路线。问题只是首先添加了约 500 条路由,而下一个 while 循环不起作用。下一个 while 循环显示在 CLI 中工作,但实际上没有添加路由。

但是如果我使用 1 个 while 循环来添加 1000 个路由。我将 while 循环计数器从 {$i &lt; 3 } 更改为 {$i &lt; 5 } 并且它可以工作。

不知何故,第二个循环没有正确执行。

【问题讨论】:

  • 更新:脚本中的执行顺序很奇怪。如果我在 while 循环之后放一些 puts "statement" 。这些语句首先打印 - 然后循环运行。 tcl脚本运行顺序是否有一些定义的行为?
  • 您没有显示您的#! 行,但您必须使用expecttclsh 运行您的程序并添加行package require Expect(大写E)

标签: while-loop tcl


【解决方案1】:

使用*# 可能有点棘手,因为它也可能匹配零次出现。取而代之的是,我们可以为提示定义正则表达式,它将匹配到行尾(即使用$

sleep 1
set prompt "#(\\s+)?\$" 
set i 1
while {$i < 3 } {
    set j 2
    while {$j < 255} {
        send "ip route 2.2.$i.$j 255.255.255.255 4.4.4.1\r"
        expect -re $prompt
        incr j
    }
    incr i
}

sleep 1

set k 1
while {$k < 3 } {
    set l 2
    while {$l < 255} {
        send "ip route 1.1.$k.$l 255.255.255.255 1.1.1.5\r"
        expect -re $prompt
        incr l
    }
    incr k
}

这应该可行。如果没有,请添加exp_internal 1 并检查调试信息。顺便说一句,不要保留不必要的expect 语句,它们只会根据timeout 值延迟执行。

正则表达式的解释如下,

【讨论】:

  • @tcpip,注意 Dinesh 也移动了 expect 语句。
  • @Dinesh:您的解决方案显着提高了脚本的性能。我观察到单独的路线被添加,这与之前在一组 6-7 条路线中的“突发”添加路线不同。然而,约 500 条路线逃避添加的问题是不同的,而且是一个愚蠢的问题。我在第二个循环ip route 1.1.$k.$l 255.255.255.255 1.1.1.5 中添加的路由具有相同的目的地和网关 IP,根据内部逻辑,这些路由失败了。
  • @tcpip :所以,从技术上讲,我的回答至少对性能有所帮助。
【解决方案2】:

我将两个循环合二为一,并在其中一个路由命令中更改了目标 IP,之前目标和网关 IP 重叠 - 1.1.$k.$l 255.255.255.255 1.1.1.5

set prompt "#(\\s+)?\$"
set i 1
while {$i < 3 } {
    set j 2
    while {$j < 255} {
        send "ip route 2.2.$i.$j 255.255.255.255 4.4.4.1\r"
        send "ip route 3.3.$i.$j 255.255.255.255 1.1.1.5\r"
        expect -re $prompt
        incr j
    }
    incr i
}

【讨论】: