Consider scenario of the sort:
#start of the script
proc A {host_ip} {
spawn ssh $host_ip
#possibly 1 to n expect statements to pattern
#match on the output of the spawned process
}
proc B {} {
#pattern match using expect statements on the
#output of the spawned process in A
}
proc C {} {
#pattern match using expect statements on the
#output of the spawned process in A
}
#call the proc's
A $some_IP
B
C
#pattern match here, not part of a procedure,
#but an expect statement to match output of
#the spawned process in A
#end of the script
From reading Expect/Tcl online documentation it appears I have 2 options:
return PID of the spawned process in A, and then explicitly use it in expect statements outside of A using the expect statement form:
expect -i $PID_FROM_A ...
there appears to be some magic/global variable that if its value is set to PID of the spawned process in A, then all expect statements in the script can pattern match on the output of the spawned process in A.
1 will work, I have not tested, but the documentation is very clear on this. I prefer 2 because I dont want to litter the script with explicitly passing the PID to each expect statement, but I dont know which global variable to override (if there is one). Any help is appreciated. Thanks.
The magic variable is called spawn_id
. You have to put global spawn_id
inside a procedure that calls spawn
(before the spawn
), but otherwise can leave it undeclared. This is because when Expect reads a variable, it searches more than just the current scope, but when it writes a variable it writes just to the current scope (this is not normal Tcl behaviour; Tcl generally always reads and writes from the current scope only unless explicitly told otherwise). From the Expect manual:
Expect takes a rather liberal view of scoping. In particular, variables read by commands specific to the Expect program will be sought first from the local scope, and if not found, in the global scope. For example, this obviates the need to place "
global timeout
" in every procedure you write that usesexpect
. On the other hand, variables written are always in the local scope (unless a "global
" command has been issued). The most common problem this causes is whenspawn
is executed in a procedure. Outside the procedure,spawn_id
no longer exists, so the spawned process is no longer accessible simply because of scoping. Add a "global spawn_id
" to such a procedure.
Thus, all you need to do is to change A
to be this:
proc A {host_ip} {
global spawn_id
spawn ssh $host_ip
#possibly 1 to n expect statements to pattern
#match on the output of the spawned process
}