Fail If a Script Expects Input or Entering Passwords

Fail if a script expects input or entering passwords

Rather than trying to close standard input or standard error, you might be better off just using a short expect script that bails out if it sees a password prompt. For example:

#!/bin/bash

cd "$1"

expect -c '
log_user 0
spawn git fetch
expect -timeout 30 -re "ass(phrase|word)" { exit 1 }
'

# Do something based on the exit status of the expect script.
[[ $? -eq 1 ]] && { echo 'Password prompt detected!' >&2; exit 1; }

The expect script will return with exit status 1 if it sees a password or key passphrase prompt. The bash script is then free to do likewise, or to take other action.

Hope that helps!

Hitting a return at password prompt in expect script instead of sending password

In a here-doc, variables like $Username and $Password are being expanded by the shell, so they're not seen as literals for Expect to expand. Since those shell variables aren't set anywhere, they're being expanded to null strings. As a result, it's executing ssh @$FQDN and sending an empty password.

You need to escape the $ so that Expect can process them.

You also don't need the set FQDN line in the Expect script, since you're using the shell variable for that.

#!/usr/bin/bash
FQDN=$1
LogFile=/tmp/Router_${FQDN}.txt
> $LogFile
expect -d <<EOF > $LogFile
set timeout 20
set Username "user"
set Password "***$$$"
spawn ssh \$Username@$FQDN
expect "*assword:"
send "\$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
expect eof
EOF
cat $LogFile

Or you could set them as shell variables, just like FQDN.

#!/usr/bin/bash
FQDN=$1
Username=user
Password="***$$$"
LogFile=/tmp/Router_${FQDN}.txt
> $LogFile
expect -d <<EOF > $LogFile
set timeout 20
spawn ssh $Username@$FQDN
expect "*assword:"
send "$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
expect eof
EOF
cat $LogFile

How can I make an expect script prompt for a password?

Use expect's stty command like this:

# grab the password
stty -echo
send_user -- "Password for $user@$host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)

#... later
send -- "$pass\r"

Note that it's important to call stty -echo before calling send_user -- I'm not sure exactly why: I think it's a timing issue.

expect programmers should all read the book: Exploring Expect by Don Libes

How to use a linux expect script to enter answer a prompt for password

From the comment I got from glenn jackman I was able to figure out that the password prompt was not being matched. I changed my first line to #!/var/bin/expect -d which provided the necessary debugging output to find out the problem and fix it.

Thanks Glenn!

Enter sudo password while in expect script

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.

Expect Script - Auto Password

This is the part you're having trouble with:

spawn ssh "root@$ip mkdir -p .ssh"
expect "password:"
send "root\r"
expect "(yes/no)? "
send "yes\r"

After you send the password you're waiting 30 seconds for (yes/no? to appear, but it might not appear if you've connected to that machine before. You want to conditionally expect that y/n prompt:

spawn ssh "root@$ip mkdir -p .ssh"
expect {
"(yes/no)? " { send "yes\r"; exp_continue }
"password:" { send "root\r" }
}
expect eof

That form of the expect command allows you to look for multiple strings simultaneously. If the first one seen is "(yes/no)? ", then send "yes" and continue with this expect command. When you see "password:", send the password and let the expect command end.

You might want to change the second spawn command
so a shell can handle the pipeline.

set cmd [format {cat "~/.ssh/id_rsa.pub" | ssh "root@%s" 'cat >> .ssh/authorized_keys'} $ip]
spawn sh -c $cmd


Related Topics



Leave a reply



Submit