Use Expect in a Bash script to provide a password to an SSH command
Mixing Bash and Expect is not a good way to achieve the desired effect. I'd try to use only Expect:
#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
# Use the correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "my_password\r"
interact -o -nobuffer -re $prompt return
send "my_command1\r"
interact -o -nobuffer -re $prompt return
send "my_command2\r"
interact
Sample solution for bash could be:
#!/bin/bash
/usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'
This will wait for Enter and then return to (for a moment) the interactive session.
Using 'expect' command to pass password to SSH running script remotely
You are doing it wrong in two means:
If you want
expect
to interact withssh
, you need to startssh
fromexpect
script and not before.If you put the script (
/path/to/script/test.sh
) tostdin
ofssh
, you can't communicate with thessh
process any more.
You should rather copy the script to remote host using scp and then run it.
Expect script might look like this:
/usr/bin/expect <<EOF
spawn ssh -p$port root@$ip
expect "password"
send "$Spass\r"
expect "$ "
send "/path/to/script/on/remote/server/test.sh\r"
expect "$ "
interact
EOF
Provide password to ssh command inside bash script, Without the usage of public keys and Expect
First of all: Don't put secrets in clear text unless you know why it is a safe thing to do (i.e. you have assessed what damage can be done by an attacker knowing the secret).
If you are ok with putting secrets in your script, you could ship an ssh key with it and execute in an ssh-agent
shell:
#!/usr/bin/env ssh-agent /usr/bin/env bash
KEYFILE=`mktemp`
cat << EOF > ${KEYFILE}
-----BEGIN RSA PRIVATE KEY-----
[.......]
EOF
ssh-add ${KEYFILE}
# do your ssh things here...
# Remove the key file.
rm -f ${KEYFILE}
A benefit of using ssh keys is that you can easily use forced commands to limit what the keyholder can do on the server.
A more secure approach would be to let the script run ssh-keygen -f ~/.ssh/my-script-key
to create a private key specific for this purpose, but then you would also need a routine for adding the public key to the server.
Expect script: Create method to login to a remote server using ssh and send commands after method has returned
When you run spawn
inside a proc, the variable spawn_id
is created in the current stack frame, making it a local variable unless special measures are taken.
With that knowledge, the solution is simple: Declare spawn_id
as a global before running the spawn
command:
proc login {username node_address password prompt password_prompt} {
global spawn_id
puts "Attempting login to ${node_address}"
spawn ssh ${username}@${node_address}
expect -re ${password_prompt} {send -- "${password}\n"}
expect -re ${prompt} {send -- "sudo su - kompuser\n"}
puts "Logged in to the node ${node_address} successfully"
}
I believe you don't need to do that in the other procs. But for consistency, I would.
Expect if condition with ssh password
In cases 2 and 3 you don't need exp_continue
because you are stopping the connection process.
For case 2, I don't think you really want to send a control-C. When you do this interactively, typing control-C has the effect of sending a signal to kill the process you are interacting with. What you really want is to stop the ssh
process, so instead of send -- "^C";exp_continue
you should just do close
.
Related Topics
How to Write a Bash Script to Restart a Process If It Dies
Bash Script Prints "Command Not Found" on Empty Lines
"Failed to Load Platform Plugin "Xcb" " While Launching Qt5 App on Linux Without Qt Installed
Linking Openssl Libraries to a Program
How to Determine Whether a Given Linux Is 32 Bit or 64 Bit
Git Asks For Username Every Time I Push
Retrieve Cpu Usage and Memory Usage of a Single Process on Linux
Exit Code of Variable Assignment to Command Substitution in Bash
How to Compare Two Datetime Strings and Return Difference in Hours? (Bash Shell)
Core Dump File Is Not Generated
How to Send a File as an Email Attachment Using Linux Command Line
Using Openssl to Get the Certificate from a Server
Fastest Way to Find Lines of a File from Another Larger File in Bash
How to Set the Working Directory of the Parent Process
The Difference Between Fork(), Vfork(), Exec() and Clone()
Shell Command to Tar Directory Excluding Certain Files/Folders
Curl to Access a Page That Requires a Login from a Different Page