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.
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