1

I'm using a tcl script to open an ssh connection to a linux machine and open a virtual switch application. Inside the switch CLI I add >1000 IP routes.

I run the script as = ./script_name.tcl and not via tclsh because that tends to give me some errors.

The problem is somewhere in how tcl interprets while loop inside tcl script. My while loops -

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
}

I use 2 while loops for adding ~500 routes each, so the total should make >1000 routes. The problem is only first ~500 routes are added and the next while loop doesn't works. The next while loop displays to be working in CLI, but the routes are actually not added.

But if I use 1 while loop to add 1000 routes. I change the while loop counter from {$i < 3 } to {$i < 5 } and it works.

Somehow the second loop is not getting executed properly.

2
  • Update: The executing order in the script is very weird. If I put some puts "statement" after the while loops. Those statements are printed first - and the loop runs afterwards. Is there some defined behavior of tcl script running order? Commented Nov 17, 2015 at 12:37
  • You don't show your #! line, but you have to run your program with expect, or with tclsh and add the line package require Expect (with a capital E) Commented Nov 17, 2015 at 19:12

2 Answers 2

2

Using *# can be bit tricky as it might match zero occurrences as well. Instead of that, we could define the regular expression for the prompt which will match up to the end of line (i.e. using $)

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
}

This should work. If not, add exp_internal 1 and check the debug information. By the way, don't keep unnecessary expect statements which will do nothing but delaying the execution based on the timeout value.

The explanation for the regular expression is as follows,

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

@tcpip, note that Dinesh moved the expect statements as well.
@Dinesh: Your solution significantly improved the performance of the script. I observed individual routes getting added unlike previously the 'burst like' addition of routes in a group of 6-7 routes. However the problem of ~500 routes escaping addition was different and a silly one. The routes which I was adding in second loop ip route 1.1.$k.$l 255.255.255.255 1.1.1.5 were having same destination and gateway IP which were failing according to internal logic.
@tcpip : So, technically, my answer helped at least for performance.
0

I clubbed the two loops in one and also changed the destination IP in one of the routes command where previously the destination and gateway IP were overlapping - 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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.