Checking all the systems on a subnet, using Expect and Tk
Archive - Originally posted on "The Horse's Mouth" - 2011-09-18 21:05:12 - Graham EllisThere are times that we want to check the connectivity of all the systems on our subnet - to see which machines are present, and which are not. Pinging them one at a time is a bit slow, but pinging them all at once in a simple script sets up too many connections and the script is likely to fall over. Then how do you display the results quickly and easily?
I have updated an "old favourite" script - "tkpingle" which check out a series of systems named on the command line - to test a complete subnet. Systems are "ping"ed 16 at a time, and layed out in a grid rather than a single column



The complete script is [here]
Some elements worthy of comment (even for people who have used a bit of Tk and expect before ...
* Making a grid uniform
The following - applied to one label in each row and each column - ensures that all cells are going to be of the same width and height.
grid rowconfigure . .la_$syslab -weight 1 -uniform w
grid columnconfigure . .la_$syslab -weight 1 -uniform w
* Closing out complete or incomplete pings
Spawning processes uses up system resources that need to be released if there's further resources needed (if there wasn't anything further to do, we could get away without doing this as the script will clean up on exit).
The use of catch is to avoid crashing the script if the script had closed the resource already, and the wait is to ensure that the resource truely is closed.
foreach done $tidy {
if { [catch {close -i $done} msg ] } {
# ignore
} else {
wait -i $done
}
}
* Spawning parallel processes A
Processes that are spawned set their ID in the global variable $spawn_id. We save all the spawn_ids away so that we can check how all the processes are running in parallel later on.
for {set k 0} {$k < 16} {incr k} {
set val [expr $k + $j * 16]
set system "$subnet.$val"
spawn ping -c 3 $system
set id($system) $spawn_id
* Modal buttons
In order to avoid a second series of test being started while the previous set is still running, we disable the "run" button as soon as its been pressed ...
.redo config -state disabled
... and we re-enable it just as it finished its work.
.redo config -state normal