Reputation: 304
I am trying to call an expect script from bash and have it return exit code in case of e.g. Connection Timeout.
Basically the bash script is calling expect like this:
if [[ -f $1 ]]; then
do something
else
script.exp $device
# here I want to evaluate the exit code but it is always 0
fi
I found some previous questions about it and that the right way to catch exit codes is:
expect eof
catch wait result
exit [lindex \$result 3].
The expect script:
#!/usr/bin/expect
exp_internal 1
log_user 1
set timeout -1
set hostname [lindex $argv 0]
set prompt "sftp>";
if { $hostname == "blah" } {
set username "user1"
set password "pass1"
} else {
set username "user2"
set password "pass2"
}
spawn sftp $username@$hostname "-o ConnectTimeout=3"
expect {
"timeout" {
puts "A timeout occured"
exp_continue
}
"password:" {
send "$password\r"
exp_continue
}
"sftp>" {
send "cd cfg\n"
expect $prompt
send "get * /some/dir/$hostname\n"
expect $prompt
send "get running-config /some/dir/$hostname-config\n"
expect $prompt
send "exit\r";
exp_continue
}
}
expect eof
catch wait result
exit [lindex \$result 3]
When I just test the expect script to see what happens, I get this error:
expect: spawn id exp4 not open
while executing
"expect eof"
I've tried moving expect eof around but it does not change the behavior. It states that the spawned process id is not open, which I guess is correct as it has exited with Timed Out/Connection closed?
Upvotes: 0
Views: 2149
Reputation: 584
exp_continue
after send "exit\r"
, otherwise EOF will be consumed by the expect { ... }
block and another expect eof
would fail.lindex \$result 3
to lindex $result 3
as in the comments.Upvotes: 1
Reputation: 246764
(Incorporating the previous comments)
Add it into the previous expect command, but with no body:
expect {
timeout {...}
password: {...}
sftp> {...}
eof
}
wait result
if {[lindex $result 2] == 0} {
exit [lindex $result 3]
} else {
error "system error: errno [lindex $result 3]"
}
Upvotes: 0