After struggling few days with expanding variable inside the expect heredoc, finally i came across an another approach i thought may be helpful to someone in need. My requirement was to pass command and password to a shell function, execute the command in remote host as part of expect heredoc and get the return exit code.
Example:
function shell_function {
# Get the command and password as arguments
# Run command using expect
# Return the exit code
}
shell_function <cmd> <password>
echo $?
Like everyone else expanding of variable inside the heredoc was a problem, which required exporting the value into an environment variable and use env
to get the variable inside heredoc. Since, password was one of the arguments i didn't want to store it as part of an environment variable. So, instead of enclosing heredoc opening with single quotes, the variables of heredoc have been escaped. This allowed the direct usage of arguments passed.
Following is the final script:
#! /bin/bash
# This function runs a command like 'ssh' and provides the password
function run_with_password {
cmd="$2"
paswd="$1"
expect << END
set timeout 60
spawn $cmd
expect {
"yes/no" { send "yes\r" }
"*assword*" { send -- $paswd\r }
}
expect EOF
catch wait result
exit [lindex \$result 3]
END
}
my_password="AnswerIS42Really?"
cmd_to_run="ssh userid@hostname"
cmd_to_run="$cmd_to_run ls .sawfish"
run_with_password $my_password "$cmd_to_run"
echo "Command run code: $?"
In the above code the escaped expect variable is $result
. After changing the variable to \$result
, the script started working like charm.
My sincere thanks to users who have provided answers to following questions, which served as a stepping stones to reach my solution.
Douglas Leeder: help with expect script, run cat on remote comp and get output of it to the variable
glenn jackman: How to return spawned process exit code in Expect script?