[[add information about expect's spawn command, pointers to its man page on http://www.tcl.tk/man/, etc.]] spawn creates a session with a program or remote device that [Expect] can manage. Spawned sessions can be automated using other Expect commands, such as expect, [interact] and exp_send. The [man] page for spawn is actually part of the Expect man page http://www.tcl.tk/man/expect5.31/expect.1.html. A very simple example - [ping] an ip address: #!/bin/sh # The next line is executed by /bin/sh, but not tcl \ exec /homes/ashnoc01/noc/rbacon/tcl/ActiveTcl/bin/tclsh8.4 $0 ${1+"$@"} package require Expect spawn -noecho /usr/local/bin/nping -c 5 $argv log_user 0 expect { "\r" { puts -nonewline "$expect_out(buffer)" exp_continue } eof { puts -nonewline "$expect_out(buffer)" } } puts "AutoPing finished\n" exit Output: > AutoPing 62.188.74.130 PING 62.188.74.130: 64 data bytes EchoReply from 62.188.74.130: len=64 ttl=242 seq=0 time=81.157 ms. EchoReply from 62.188.74.130: len=64 ttl=242 seq=1 time=80.768 ms. EchoReply from 62.188.74.130: len=64 ttl=242 seq=2 time=80.709 ms. EchoReply from 62.188.74.130: len=64 ttl=242 seq=3 time=80.915 ms. EchoReply from 62.188.74.130: len=64 ttl=242 seq=4 time=80.940 ms. ----62.188.74.130 PING Statistics---- 5 transmitted, 5 received, 0.00% packet loss. round-trip (ms) min/avg/max = 80.709/80.898/81.157 var/sdev/skew/kurt = 0.030/0.174/0.323/1.311 AutoPing finished ---- ''[escargo] 20 Sep 2005'' - Let's see if I remember this correctly. A frequently made mistake in [Expect] is to spawn a new process in a procedure, and then not assign the returned process identifier to anything that gets it out of the proc local scope. Without the '''pid''' to pass to other Expect commands, they won't work as intended. It might also be possible to pass the ''wrong'' '''pid''' because of the overwriting (or not overwriting) the ''spawn_id''. ----- ''[RJ] 21 Sep 2005'' - You remember correctly. An important point. An example of that: proc connect_server {server} { spawn -noecho rlogin $server set sid($server) $spawn_id return $sid($server) } set sid(myserver) [connect_server myserver.org] set sid(otherserver) [connect_server otherserver.org expect $sid(myserver) "%" exp_send "ls -l\r" expect $sid(otherserver) "%" exp_send $sid(otherserver) "ls -l\r" expect $sid(myserver) "%" set output_from_myserver $expect_out(buffer) expect $sid(otherserver) "%" set output_from_otherserver $expect_out(buffer) ....do stuff with the server output Arrays of spawn_ids allow you to connect to multiple servers and hold those connections open indefinitely, switching at will. ''[escargo]'' - I note that '''connect_server''' uses an array, '''sid''', that is not declared as [global]. Is this one of those cases where variable scoping in [expect] is different than [Tcl]? (That is, in this case, expect doesn't find the variable in the local scope so it automatically checks the global scope for it.) ''[RJ]'' - Nope - Expect does not globalize variables unless told to. It really didn't need to be an array in the proc, just a variable. The return sends it back. But yes, it could have been a global variable - thus negating the need for returning it in the proc. I'm generally very bad at polluting the global namespace, so I try not to when I put up something anyone will actually look at. ;) ---- That example of using Expect to drive ping is totally unmotivating. You might as well use exec, no? Expect's strength comes from taking control of interactive processes like passwd or telnet. [RJ] The example was a request in [Ask, and it shall be given # 3], placed here to kill the second bird (an example of using spawn). BUT, suppose the "\r" branch tracked the successful ping ratio and the ping was endless. The data could be used in graphical widget to display server availability realtime. Expect's power is limited only by the programmer's creativity IMHO. I would say it's power is best illustrated by it's ability to make non-interactive processes interactive. ---- [Category Command] | [Category Expect]