ActiveState Community

Spawning Multiple Telnet Sessions with Expect

Posted by dandan on 2008-07-20 03:19

Hello,
I need to spawn multiple telnet sessions in parallel to speed up a process. I have the following code which works fine in a serial manner i.e. doing one at a time.

########### IP Scan Code Fragment ###################
set list ""
lappend list 172.27.132.5 172.27.132.6 ... ... etc etc
global netip
global netip1
foreach {netip} [lindex $list] {
set netip1 $netip
.top3.tex22 insert end "Opening Connection to $netip1.............\n"
.top3.tex22 see end; update
set ttwait0 [open [pwd]/settings/ttwait.txt r]; gets $ttwait0 ttwait; close $ttwait0
catch {exec ping -n 2 -w $ttwait $netip} 1a; update idletasks
set ttl [regexp "TTL expired in transit" $1a]
set k3 [regexp "Reply from" $1a]
if {$k3 == 0 || $ttl == 1} {
.top3.tex22 insert end "$netip1: No Response\n\n"; .top3.tex22 see end; update}
if {$k3 == 1 && $ttl == 0} {
spawn [pwd]/telnet.exe $netip1
set netip $spawn_id

expect {
-i $netip eof {
.top3.tex22 insert end "$netip1: Reply from unknown device: cannot Open Telnet port 23\n\n"
.top3.tex22 see end
catch {exp_close -i $netip} a
catch {exp_wait -i $netip} b
update
}

-i $netip -re "invalid password" {
.top3.tex22 insert end "$netip1: Reply from unknown device: invalid userid/password\n\n"
.top3.tex22 see end
catch {exp_close -i $netip} a
catch {exp_wait -i $netip} b
update
}

-i $netip -re "incorrect" {
.top3.tex22 insert end "$netip1: Reply from unknown device: invalid userid/password\n\n"
.top3.tex22 see end
catch {exp_close -i $netip} a
catch {exp_wait -i $netip} b
update
}

-i $netip timeout {
.top3.tex22 insert end "$netip1: Connection timed-out\n\n"
.top3.tex22 see end
catch {exp_close -i $netip} a
catch {exp_wait -i $netip} b
update
}

-i $netip "Username:" {
set send_slow {10 .001}
set user99 [.top3.entmuser get]
set pass99 [.top3.entmpass get]
send -s -i $netip "$user99\r"
expect -i $netip "Password: "
send -s -i $netip "$pass99\r"
sleep 3
expect {
......
......
}
.top3.tex22 insert end "$netip1: Reply from M-Series\n\n" pop
.top3.tex22 see end
.top3.tex22 tag configure pop -background green
}

-i $netip "Login:" {
set send_slow {10 .001}
set user99 [.top3.entmuser get]
set pass99 [.top3.entmpass get]
send -i $netip -s "$user99\r"
expect -i $netip "Password: "
send -i $netip -s "$pass99\r"
sleep 3
expect {
......
......
}
.top3.tex22 insert end "$netip1: Reply from B-Series\n\n" pop
.top3.tex22 see end
.top3.tex22 tag configure pop -background green
}
}}}
########## End Code Fragment ########################

I believe I need to use expect_background. But a tip on how to use this within my code above would be a great help. I've tried implementing it but it only seems to do anything on the last IP address.

pathuri | Tue, 2009-09-01 05:59

I ran into the exactly similar situation today and tried to search for the solution over internet. I ended up coming across your question (unanswered).

All of a sudden, mysteriously 'this idea' struck in my mind and could successfully solve my problem.

The following method worked for me:

# spawn all connections
foreach conn $allconnections {

spawn telnet $conn
lappend spawn_id_list $spawn_id

}

# run expect script for all connections individually
foreach id $spawn_id_list {

# this is important - for unknown (to me) reasons
set spawn_id $id

send "your_send_message"
expect "your_expect_pattern"

}

The reason "set spawn_id $id" is required could be that as the expect is run in single threaded mode, it can only run one session at a time.

And i really am not understanding why the id passed to the "send" command is just ignored always and the messages sent only to the last spawned session - may be the reason here is similar to "why the spawn_id in the command execution level is updated instead of *returning* the spawn_id".

I am sorry - I am novice to expect and could not do this using "expect_background".

I am expecting somebody (including you) to explain why the "spawn_id" passed to the "send" command is simply ignored and why does the "send" always uses the "spawn_id" available in the execution level to send the messages to.

Please post-back if the idea helped you.

Best Regards,
Mallik