By mrkz1974
Hello there. I have an expect script that I use to routinely apply certain commands to all Cisco routers within our
SSH network. The output file has been modified so only loopback
IP addresses are shown if it ran succesfully, like this:
*******************************************
SSH Login successful for 10.x.x.1
*******************************************
SSH Login successful for 10.x.x.2
*******************************************
etc…
We recently transitioned to SSH, (and since I’m a network guy and not a programmer it was a PAIN to make this work). There is a request now to capture ALL the expect output and I’m wondering what the best way to do this would be without changing the edited output. Maybe write the whole thing to another file, maybe using another script to capture all the log from this script, I don’t know. Here’s the script:
Code:
#!/usr/local/bin/expect -f
proc sshLoginV2 {host} {
set timeout 10
set sshUser "USER"
set sshPass "PASS"
spawn -noecho /usr/bin/ssh -o StrictHostKeyChecking=no $sshUser@$host
expect {
"assword:" {
send "$sshPassr"
expect {
"*#" {
return "success: logged in via SSH to $host"
}
"Access denied" {
return "error: access denied, incorrect password sent to $host"
}
}
}
timeout {
return "error: SSH login to $host timed out"
}
eof {
return "error: connection to $host failed"
}
}
}
#---open input file
set infile [open IPLIST r]
#---set the send_slow variable to 1.05 seconds
set send_slow {1 .01}
#---set output file variable
set outfile [open SCRIPT-RESULTS.txt w]
#---set expect timeout variable to 10 seconds
set timeout 7
#---turn off screen logging
log_user 0
#---foreach line in the input file
foreach host [split [read $infile] "n"] {
#---have to flush STDOUT buffer on each iteration of loop
flush $outfile
puts $outfile "*******************************************"
#---set PID variable with pid of spawned ping
spawn /usr/sbin/ping6 $host
set pingSpId $spawn_id
expect {
-i $pingSpId eof {
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
}
-i $pingSpId timeout {
puts "Ping timed out for $host"
puts $outfile "Error: Cannot ping $host"
puts $outfile "*******************************************n"
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
continue
}
-i $pingSpId "no answer from $host" {
puts "No answer from $host"
puts $outfile "Error: Cannot ping $host"
puts $outfile "*******************************************n"
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
continue
}
-i $pingSpId "unknown host $host" {
puts "Unknown host $host"
puts $outfile "Error: Cannot ping $host"
puts $outfile "*******************************************n"
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
continue
}
-i $pingSpId "0 packets received" {
puts "Cannot ping host $host, 0 packets received"
puts $outfile "Error: Cannot ping $host"
puts $outfile "*******************************************n"
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
continue
}
-i $pingSpId "$host is alive" {
puts "$host is alive"
catch {exp_close -i $pingSpId} a
catch {exp_wait -i $pingSpId} b
}
}
#---call sshLogin proc from common.tcl
set sshMsg [sshLoginV2 $host]
if {[regexp "error" $sshMsg]} {
puts $outfile "SSH Login failed for $host"
puts $outfile "Reason: $sshMsg"
continue
} elseif {[regexp "success" $sshMsg]} {
puts $outfile "SSH Login successful for $host"
} else {
puts $outfile "Not sure what happened to SSH login for $host"
continue
}
set tlntSpId $spawn_id
#---hit the enter key once, just to see prompt
send -s -i $tlntSpId "r"
expect {
-i $tlntSpId eof {
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
-i $tlntSpId timeout {
puts $outfile "error: do not see switch prompt"
puts $outfile "*******************************************n"
send "exitr"
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
-i $tlntSpId "*#"
}
#---set terminal length to 0
send -s -i $tlntSpId "term len 0r"
expect {
-i $tlntSpId eof {
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
-i $tlntSpId timeout {
puts $outfile "error: timeout sending code to $host"
puts $outfile "*******************************************n"
send "exitr"
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
-i $tlntSpId "*#"
}
#---send commands
send -s -- "sh dlsw transparent map r"
expect *
sleep .1
send -s -- "sh int loopback 0 | incl 10.r"
expect *
sleep .2
send -s -- "exitr"
puts $outfile "*******************************************n"
flush $outfile
#---send exit to switch
send -s -i $tlntSpId "exitr"
expect {
-i $tlntSpId eof {
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
-i $tlntSpId timeout {
puts $outfile "error: timeout exiting $member on $host"
puts $outfile "*******************************************n"
send "exitr"
catch {exp_close -i $tlntSpId} a
catch {exp_wait -i $tlntSpId} b
}
}
}
close $outfile
To recap, I’m looking to write for the whole logging output to another file and I’m wodering what is the best way to do this. Thanks!
Source: FULL ARTICLE at The UNIX and Linux Forums