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
Print Differences of File1 to File2 Without Deleting Anything from File2
Python Error "Attributeerror: 'Module' Object Has No Attribute 'Sha1'"
Export_Symbol in Kernel Module | Undefined Symbol During Insmod
Ada Program Works in Linux But Not in Gps Windows 10
"Echo" Output Different Answer by Sh and Bash
How to Print the Nth (5Th) Line of Every File Preceded by the Filename Using Any Linux Tool
How to Display Filename from a Column Using Awk
How to Draw 2D Diagram in Linux
Gitlab Ssh Requests Password and Ignoring Ssh Keys
Top Command Output Is Empty When Run from Cron
Using Ssh to Run a Cleartool Command with Agruments on Remote a Linux MAChine
R Programming - Submitting Jobs on a Multiple Node Linux Cluster Using Pbs
Changing the Owner of an Existing Process in Linux
Gatttool Non-Interactive Mode --Char-Write
How to Not Emit Local Symbols in Nasm So That Gdb Disas Won't Stop at Them
Docker Overlay2: Error Walking File System: Oserror [Errno 40] Too Many Levels of Symbolic Links