Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enter sudo password while in expect script

Tags:

bash

expect

tcl

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.

like image 476
adamm Avatar asked Mar 19 '26 06:03

adamm


2 Answers

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.

like image 141
meuh Avatar answered Mar 22 '26 04:03

meuh


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
like image 33
Donal Fellows Avatar answered Mar 22 '26 04:03

Donal Fellows



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!