我有以下bash脚本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
包含:
53.12.45.74 my_username my_password
54.12.45.74 my_username my_password
57.12.45.74 my_username my_password
根据我的理解,while read ip user pass; do […] done < servers.txt
应循环遍历servers.txt
的所有三行。
但是,当我尝试运行它时,它只执行一次迭代:
ubuntu@server:~$ bash deploy.sh
53.12.45.74
yo
done
ubuntu@server:~$
为什么?
如果循环只是:
while read ip user pass; do
echo $ip
done < servers.txt
它确实执行了所有三次迭代:
ubuntu@server:~$ bash deploy.sh
53.12.45.74
54.12.45.74
57.12.45.74
ubuntu@server:~$
答案 0 :(得分:4)
sshpass
正在控制stdin
或可能替换它并导致while
循环丢失重定向stdin
的输入。
要解决此问题,请避免从stdin读取。
首先,使用while
循环将文件加载到数组中。
while read line; do
entries+=("$line")
done < servers.txt
接下来,使用for
循环来解析这些行并在此循环中执行sshpass
。
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
第二个循环不会从stdin
读取。
但我会建议使用与当前stdin
不同的描述符Rany Albeg Wein answer。
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
答案 1 :(得分:0)
#!/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
所以,现在它有效。