I have a problem with this in expect:
spawn ssh f...@123.123.123.123 ls -l > /tmp/mylog 2>&1
while (1) {
expect timeout { puts "get timeout\n"; exit 99} \
"Are you sure*" { send "no\r"; break; } \
"*password: $" { send "$passwd\r"; continue; } \
eof { puts "get eof\n"; break;} \
default { puts "get default\n"; break;};
}
The problem is if "ssh" failed, like teh script get a dummy ip
address, the erro message, "ssh: connect to host xxx.xxx.xxx.xxx port
22: No route to host" didn't get to /tmp/mylog/. This is because
expect think my command is
'spawn ssh f...@123.123.123.123 "ls -l > /tmp/mylog 2>&1 ' but what I
really want is
I have a problem with this in expect:
spawn ssh f...@123.123.123.123 ls -l > /tmp/mylog 2>&1
while (1) {
expect timeout { puts "get timeout\n"; exit 99} \
"Are you sure*" { send "no\r"; break; } \
"*password: $" { send "$passwd\r"; continue; } \
eof { puts "get eof\n"; break;} \
default { puts "get default\n"; break;};
}
The problem is if "ssh" failed, like the script get a dummy ip
address, the erro message, "ssh: connect to host 123.123.123.123 port
22: No route to host" didn't get to /tmp/mylog. This is because
expect think my command is
'spawn ssh f...@123.123.123.123 "ls -l > /tmp/mylog 2>&1" '
but what I really want is
'spawn "ssh f...@123.123.123.123 ls -l" > /tmp/mylog 2>&1 '
so I can catch the ssh error.
How should I correct tghe command syntax?
Eric.
The results (including errors) will come back to your expect script directly.
No need to redirect to a file - you can use expect commands to deal with them.
Bruce
I just tested. The expect script will not catch the "No route to
host". It will only catch the "eof" afterward which left me no clue
about the "eof" is from a successful action or failed one.
Eric.
On Apr 14, 2:10 pm, Bruce Hartweg <doNOT...@nowhere.com> wrote:
> Bruce- Hide quoted text -
>
> - Show quoted text -
yes it does - the eof pattern is what you want.
inside there you can look at the contents of expect_out(buffer) to see
the messages, and also the results of a call to wait will give you
the exit status of your spawned program.
Got it. Appreciate your help. Thanks very much.
Eric.
> >> - Show quoted text -- Hide quoted text -
You've got several problems with this expect script see comments
in your code:
>
> I have a problem with this in expect:
spawn does not handle redirects nor should it if you
redirect the output to a file what will expect feed on?
if you want the ssh command to write to a file on the remote system
then you need to quote the spawn command like so
spawn ssh f..@123.123.123.123 \"ls -l > /tmp/mylog 2>&1\"
> spawn ssh f...@123.123.123.123 ls -l > /tmp/mylog 2>&1
If you are interested in the output then forget the redirection and
have
expect get the information.
This is a lousy way to loop use the expect command itself
set buffer ""
expect {
-i $spawn_id
-gl "Are you sure*" {
send "no\r"
# without exp_continue it breaks out
# but we always want to wait for eof
# you can always set a "bad" variable here
# to say you exited because of this reason
}
timeout {
send_user "Timeout\n"
# on timeout try to kill the spawned process this will
# not tell you why it died but you when you access the exit
status
# you will see a sigkill signal was used so something bad
happened
# you also will be able to reuse the spawn_id and prevent
zombies
exec kill -9 $pid
exp_continue; # wait for eof
}
> while (1) {
by calling exit here you exit the expect script not the spawned
process
that tells you nothing
> expect timeout { puts "get timeout\n"; exit 99} \
why are you doing this if your not sure you want to add this to your
known hosts
try to match on endings you don't want expect sending data too soon.
Change the below to :
-re {Are you sure.*\(yes/no\)\? } { send "yes\r";
exp_continue }
> "Are you sure*" { send "no\r"; break; } \
by default expect does globing since $ is not a special globbing
character are your really getting a literal '$' character output?
always specify what type of matching you wish to see and don't use
quotes if you can help it. Below translates to :
-re {ssword: $} { .....
> "*password: $" { send "$passwd\r"; continue; } \
don't use puts in an expect script always use send_user
BTW puts adds a line feed if you dont use the -nonewline option
so in the puts command below would end up with double \n's not
so with send_user
> eof { puts "get eof\n"; break;} \
eof {
send_user "got eof\n";
# lets get the data
set buffer $expect_out(buffer);
}
}
# now lets collect the exit information
# because you wait for eof you can safely call exp_wait without the
# no hang option the exitstatus variable will be a list of 4 items
# the pid the spawn_id the Signal if any , and the exit status
# spawned processes died with.
set exitstatus [ exp_wait -i $myid ];
catch { exp_close -i $myid };
Sorry but expect does not have a default this is wrong
> default { puts "get default\n"; break;};
>
> }
>
> The problem is if "ssh" failed, like the script get a dummy ip
> address, the erro message, "ssh: connect to host 123.123.123.123 port
> 22: No route to host" didn't get to /tmp/mylog. This is because
> expect think my command is
> 'spawn ssh f...@123.123.123.123 "ls -l > /tmp/mylog 2>&1" '
> but what I really want is
> 'spawn "ssh f...@123.123.123.123 ls -l" > /tmp/mylog 2>&1 '
> so I can catch the ssh error.
>
> How should I correct tghe command syntax?
>
> Eric.
Ok lets checkout the final result, I use a tcl shell and pull in
the Expect package but you can change this to just call expect
if thats what you want
#!/bin/sh
# the next line restarts using wish \
exec /opt/usr2/bin/tclsh8.5 "$0" ${1+"$@"}
if { [ catch {package require Expect } err ] != 0 } {
puts stderr "Unable to find package Expect ... adjust your
auto_path!";
}
set pid [ spawn ssh carl@spanky ls -l ]
set myid $spawn_id;
set passwd "xxxxxx"
set bad 0;
set done 0;
exp_internal 0; # set to one for extensive debug
log_user 0; # set to one to watch action
set buffer ""
expect {
-i $myid
-re {yes/no\)\?} { send "yes\r"; exp_continue; }
-re {word: $} { send "$passwd\r"; exp_continue; }
timeout {
senduser "get timeout\n";
exec kill -9 $pid
set bad 1
exp_continue;
}
fullbuffer {
append buffer $expect_out(buffer);
exp_continue;
}
eof {
send_user "Eof detected\r"
append buffer $expect_out(buffer);
set done 1 ;
}
}
set exitstatus [ exp_wait -i $myid ];
catch { exp_close -i $myid };
puts " exitstatus = $exitstatus"
puts "buffer\n$buffer"
------------------ END Script -----------------------
Ok lets run it I called the script exitstatus.tcl
> ./exitstatus.tcl
spawn ssh carl@spanky ls -l
exitstatus = 13550 exp4 0 0
buffer
total 10496
-rw-rw-r-- 1 carl carl 1140 2008-04-03 12:52 04032008.txt
...
-rw-rw-r-- 1 carl carl 634 2008-04-10 19:17 #x.tcl#
drwxrwxr-x 4 carl carl 4096 2007-06-19 11:26 zile
>
HTH
Carl