I have an expect code inside bash script, something like this
env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
set timeout -1
spawn ./another_script.sh
expect {
"Input 1" { send -- "$env(input1)\r";exp_continue }
"Input 2" { send -- "$env(input2)\r";exp_continue }
eof
}
EOS
During the execution of another_script.sh I am prompted to enter sudo password, but I'm not able since I'm stil in expect.
What can I do in order for me to be able to enter the sudo password and for the script to continue running after that?
I don't want to save the password in the script and then pass it to expect, but I want to be able to type it in.
The answer from Donal Fellows is the right way to go, but for completeness here is the interact solution you were trying for. The command to use is
expect {
"Input 1" { send -- "$env(input1)\r"; exp_continue }
"Input 2" { send -- "$env(input2)\r"; exp_continue }
"password for" { stty -echo
interact -u tty_spawn_id -o "\r" return
stty echo
exp_continue }
eof
}
The problem you have is that you are running expect with the script on stdin, so interact has trouble unless you use -u tty_spawn_id to get it to work with /dev/tty and the user. You need to set the echo on/off on this tty explicitly, as sudo will only have done it on the pty between the spawned command and expect.
The standard way of handling an event like this is to watch for a prompt for the sudo password, supply it, and then continue. But with a long-running script, you'll want to cache the password within the expect script so that you don't have to go back to the user for it several times over a few hours. Indeed, for usability you probably need to ask for the password up front rather than waiting until the underlying system needs it.
Fortunately, expect includes support for stty so it's an easy thing to add.
env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
# Prompt for password, cribbed/converted from example on expect(1) manpage
stty -echo
send_tty "sudo password: "
expect_tty -re "(.*)\n"
send_tty "\n"
set password $expect_out(1,string)
stty echo
# Rest of the script, with clause for sending the password at the right time
set timeout -1
spawn ./another_script.sh
expect {
"Input 1" { send -- "$env(input1)\r"; exp_continue }
"Input 2" { send -- "$env(input2)\r"; exp_continue }
"assword: " { send -- "$password\r"; exp_continue }
eof
}
EOS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With