You have single quoted the string; this prevents the shell from
interpolating $server
. TCL (which is what expect
code is written in)
also uses the $server
form to interpolate variables, but you have not
set server ...
anywhere in your TCL code. Hence the error, as the
shell did not interpolate it nor did the TCL set it. One method would be
to double quote the TCL expression which will allow the shell to
interpolate in the shell $server
variable:
$ server=example; expect -c 'puts $server'
can't read "server": no such variable
while executing
"puts $server"
$ server=example; expect -c "puts $server"
example
$
However this will mean that any "
in the TCL code will need to be
escaped to protect them from messing with the shell interpolation which
will probably get ugly real fast and will be hard to debug, especially
as the commands get longer and more complicated.
$ server=example; expect -c "puts \"a server named '$server'\""
a server named 'example'
$
Another option would be to read the argument into a TCL variable, but,
alas, the -c
flag code of expect
has no access to the arguments list
in char *argv[]
as the -c
code is run before the arguments list is
made available for use by TCL. Therefore to use $server
as a TCL
variable the script would need to be rewritten in TCL:
#!/usr/bin/env expect
set fh [open testreboot.txt r]
while {[gets $fh server] >= 0} {
spawn -noecho ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 \
administrator@$server
expect -ex "Password:"
send "Hunter2\r"
expect -ex {$ }
send "sudo shutdown -r now\r"
expect -ex "Password:"
send "Hunter2\r"
interact
}
which will may need improvements for error handling, timeouts, matching
the shell prompt better, etc.