Passing a variable in a bash script to sshpass - bash

I am trying to pass a variable in a bash script to sshpass. Here is my code for reference:
NAME="HARRY"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress 'bash -s' << 'EOF'
echo $NAME
EOF
How can I pass the variable in a bash script to sshpass? Thank you!

Easiest way is using env just before running bash
NAME="HARRY"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress env NAME="$NAME" 'bash -s' << 'EOF'
echo $NAME
EOF
You can pass multiple variables with multiple env statements like
export NAME="HARRY"
export SOMEVAR="hello"
sshpass -p passwd ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress env NAME="$NAME" env SOMEVAR="$SOMEVAR" 'bash -s' << 'EOF'
echo $NAME
EOF
Be aware that your variables might be interpreted when passing them. You can avoid that by changing env NAME="$NAME" to uninterpreted version env NAME="'$NAME'"

Put it after the -p option:
password=YourPassword
sshpass -p "$password" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q ipaddress 'bash -s' <<EOF
echo "$NAME"
EOF

You can simply put a dollarsign in front of the variable name, as in this example:
Linux Prompt>cat test.txt
<here you see file content>
Linux Prompt>filename=test.txt
Linux Prompt>cat $filename
<here you see file content>

Related

Get output from a shell script that does ssh two level

I have two shell scripts like below:
Script1:
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null my_username#jump_box <<EOF
ls
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null actual_host <<EOF1
sudo docker ps --format='{{json .}}'
EOF1
EOF
Script2:
details=nothing
ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null my_username#jump_box <<EOF
ls
details=$(ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null actual_host "sudo docker ps --format='{{json .}}'")
EOF
echo "${details}"
I need the docker details in a varilable in my local machine so that I can do some operations on it. The first script runs fine and I can see the output of the docker command on my local machine but the second script doesn't work. It seems to be hung/stuck and doesn't do anything and I have to forcefully quit it.
Like the comment from #Gordon Davisson, use a jumpbox.
But you can define it in the ~/.ssh/config file, too.
HOST my_jump_box
hostname jump_box
user my_username
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
HOST actual
hostname actual_hostname
user actual_user
ProxyJump my_jump_box
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
RemoteCommand sudo docker ps --format='{{json .}}'"
Then you can just use ssh actual
To fetch the output details=$(ssh actual).
Btw. Your specific problem could also be solved by changing script2 to:
#!/bin/bash
details=$(./script1)
echo "$details"

Execute commands as different user via sudo over SSH in a justfile

I have this justfile:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
whoami
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
ENDSSH
It should:
Ask me for a password
SSH into somewhere
sudo to change the user
execute some scripts
What it does:
It asks for a password a second time.
It stucks on input (no error message).
How to solve this problem?
Update
As suggested by #xhienne, this does almost work, but it says, I use the wrong password:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
exit
ENDSSH
But this does work:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
clear-text-password
whoami
ENDSUDO
exit
ENDSSH
Update 2
The answer of #xhienne does work.
With
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
You are redirecting stdin twice:
once with |
a second time with <<
Try this:
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
sudo -S will read the password from stdin. sudo -i is a substitute for the ugly sudo su bash -l (but it needs that sudo be properly configured for -u someone)
Note that I removed the quotes around ENDSUDO. Beware of inadvertent substitutions. If you must keep ENDSUDO quoted, then you can try this instead:
{
echo "$password"
cat << 'ENDSUDO'
whoami
ENDSUDO
} | sudo -S -i -u someone
I believe the following will work, if you only want to run whoami instead of several commands:
#!/usr/bin/env bash
read -s -p 'Password: ' password
ssh somewhere whoami
echo "$password" | ssh somewhere sudo -S -u someone whoami
The -S tells sudo to read the password from stdin.
If you want to run several commands with a here-document, see #xhienne's answer.

Weird output observed on executing ssh commands remotely over ProxyCommand

Team, I have two steps to perform:
SCP a shell script file to remote ubuntu linux machine
Execute this uploaded file on remote ubuntu linux machine over SSH session using PROXYCommand because I have bastion server in front.
Code:
scp -i /home/dtlu/.ssh/key.key -o "ProxyCommand ssh -i /home/dtlu/.ssh/key.key lab#api.dev.test.com -W %h:%p" /home/dtlu/backup/test.sh lab#$k8s_node_ip:/tmp/
ssh -o StrictHostKeyChecking=no -i /home/dtlu/.ssh/key.key -o 'ProxyCommand ssh -i /home/dtlu/.ssh/key.key -W %h:%p lab#api.dev.test.com' lab#$k8s_node_ip "uname -a; date;echo "Dummy123!" | sudo -S bash -c 'echo 127.0.1.1 \`hostname\` >> /etc/hosts'; cd /tmp; pwd; systemctl status cachefilesd | grep Active; ls -ltr /tmp/test.sh; echo "Dummy123!" | sudo -Sv && bash -s < test.sh"
Both calls above are working fine. I am able to upload test.sh and also its running but what is bothering me is during the process am observe weird output being thrown out.
output:
/tmp. <<< expected
[sudo] password for lab: Showing one
Sent message type=method_call sender=n/a destination=org.freedesktop.DBus object=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello cookie=1 reply_cookie=0 error=n/a
Root directory /run/log/journal added.
Considering /run/log/journal/df22e14b1f83428292fe17f518feaebb.
Directory /run/log/journal/df22e14b1f83428292fe17f518feaebb added.
File /run/log/journal/df22e14b1f83428292fe17f518feaebb/system.journal added.
So, I don't want /run/log/hournal and other lines which don't correspond to my command in sh.
Consider adding -q to the scp and ssh commands to reduce the output they might produce. You can also redirect stderr and stdout to /dev/null as appropriate.
For example:
{
scp -q -i /home/dtlu/.ssh/key.key -o "ProxyCommand ssh -i /home/dtlu/.ssh/key.key lab#api.dev.test.com -W %h:%p" /home/dtlu/backup/test.sh lab#$k8s_node_ip:/tmp/
ssh -q -o StrictHostKeyChecking=no -i /home/dtlu/.ssh/key.key -o 'ProxyCommand ssh -i /home/dtlu/.ssh/key.key -W %h:%p lab#api.dev.test.com' lab#$k8s_node_ip "uname -a; date;echo "Dummy123!" | sudo -S bash -c 'echo 127.0.1.1 \`hostname\` >> /etc/hosts'; cd /tmp; pwd; systemctl status cachefilesd | grep Active; ls -ltr /tmp/test.sh; echo "Dummy123!" | sudo -Sv && bash -s < test.sh"
} >&/dev/null

Cannot execute the sshpass command after the the first sshpass is excuted

I am trying ssh to each host to run some command, after it is done. The second and the third sshpass command needs to be ran. However, it only run the first command, and then it stops at the second and the third sshpass command. Here is my sample script.
I call it is sshHostName.sh script, and the script contains
/usr/bin/sshpass -p 'myPassword' ssh root#hostName1 "echo 'hello1'"
/usr/bin/sshpass -p 'myPassword' ssh root#hostName2 "echo 'hello2'"
/usr/bin/sshpass -p 'myPassword' ssh root#hostName3 "echo 'hello3'"
For this example, I only see hello1 after I run ./sshHostName.sh
How to run the next (sshpass) command once the previous one completed?
Thanks.
I figured out that I need to put this option there: -o StrictHostKeyChecking=no
/usr/bin/sshpass -p 'myPassword' ssh -o StrictHostKeyChecking=noroot#hostName1 "echo 'hello1'"
/usr/bin/sshpass -p 'myPassword' ssh -o StrictHostKeyChecking=noroot#hostName2 "echo 'hello2'"
/usr/bin/sshpass -p 'myPassword' ssh -o StrictHostKeyChecking=noroot#hostName3 "echo 'hello3'"
So it is working!

Heredoc for nested command in bash

I need to ssh into a machine and execute a bunch of commands under sudo bash. Here is what I've tried:
sshpass -p "vagrant" ssh vagrant#33.33.33.100 "sudo bash -i -c <<EOF
echo
ls
echo
EOF"
But it throws me 'bash: -c: option requires an argument\n'. How can I fix this?
You need to remove -c from your command line to make it accept heredoc:
sshpass -p "vagrant" ssh vagrant#33.33.33.100 "sudo bash <<EOF
echo
ls
echo
EOF"
Also you may remove -i (interactive) option too.
bash -c expects you to provide all commands on command line so this may work too:
sshpass -p "vagrant" ssh vagrant#33.33.33.100 "sudo bash -c 'echo; ls; echo'"

Resources