Reputation: 83427
I have the following bash script deploy.sh
:
#!/usr/bin/env bash
# Some useful resources:
# while read ip user pass; do : http://unix.stackexchange.com/questions/92664/how-to-deploy-programs-on-multiple-machines
# -o StrictHostKeyChecking=no: http://askubuntu.com/questions/180860/regarding-host-key-verification-failed
# -T: http://stackoverflow.com/questions/21659637/how-to-fix-sudo-no-tty-present-and-no-askpass-program-specified-error
# echo $pass |: http://stackoverflow.com/questions/11955298/use-sudo-with-password-as-parameter
while read ip user pass; do
echo $ip
sshpass -p "$pass" ssh $user@$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done < servers.txt
servers.txt
contains:
53.12.45.74 my_username my_password
54.12.45.74 my_username my_password
57.12.45.74 my_username my_password
From my understanding, the while read ip user pass; do […] done < servers.txt
should loop over all three lines of servers.txt
.
However, when I try to run it, it only performs one iteration:
ubuntu@server:~$ bash deploy.sh
53.12.45.74
yo
done
ubuntu@server:~$
Why?
If the loop is simply:
while read ip user pass; do
echo $ip
done < servers.txt
it does perform all three iterations:
ubuntu@server:~$ bash deploy.sh
53.12.45.74
54.12.45.74
57.12.45.74
ubuntu@server:~$
Upvotes: 3
Views: 2603
Reputation: 6768
sshpass
is taking control of stdin
or possibly replacing it and causing while
loop to lose input from redirected stdin
.
To work around this issue, avoid reading from stdin.
First, load the file into an array using a while
loop.
while read line; do
entries+=("$line")
done < servers.txt
Next, use for
loop to parse the lines and execute sshpass
within this loop.
for line in "${entries[@]}"; do
set $line
ip=$1
user=$2
pass=$3
echo $ip
sshpass -p "$pass" ssh $user@$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done
The second loop doesn't read from stdin
.
But I will recommend Rany Albeg Wein answer using a separate descriptor than the current stdin
.
while read ip user pass <&3; do
echo $ip
sshpass -p "$pass" ssh $user@$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done 3<servers.txt
Upvotes: 5
Reputation: 24
#!/usr/bin/env bash
# Some useful resources:
# while read ip user pass; do : http://unix.stackexchange.com/questions/92664/how-to-deploy-programs-on-multiple-machines
# -o StrictHostKeyChecking=no: http://askubuntu.com/questions/180860/regarding-host-key-verification-failed
# -T: http://stackoverflow.com/questions/21659637/how-to-fix-sudo-no-tty-present-and-no-askpass-program-specified-error
# echo $pass |: http://stackoverflow.com/questions/11955298/use-sudo-with-password-as-parameter
while read ip user pass; do
if [ -n "$ip" ]; then
echo "IP[$ip] USER[$user] PASS[$pass]";
# dont forget to uncomment this two lines here:
#sshpass -p "$pass" ssh $user@$ip -o StrictHostKeyChecking=no -T "
#echo 'yo'
echo ""; # Just a blank line"
echo "done.";
else
echo "Empty value.";
fi
done < servers.txt
So, now it works.
Upvotes: 0