
Considere o cenário abaixo
2 VMs - 192.168.229.131, 192.168.229.132
Ambos os vms têm ip como 192.168.229.151 e 192.168.229.152 em seu /etc/hosts
arquivo
Digamos que haja cerca de 50 vms como eu disse acima. Mas, a partir de agora, estou considerando apenas os 2 acima.
Salvei ips das 2 vms em um arquivo chamado server
#cat server
192.168.229.131
192.168.229.132
Abaixo está o roteiro
#!/bin/bash
cat server | while read line
do
/usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@$line << EOF
echo successfully logged in $line
MYIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
for i in 151 152
do
echo 192.168.229.\$i >> errips
done
for data in `cat errips`
do
echo data currently has $data
grep $data /etc/hosts
if [ $? -eq 0 ]
then
sed -i "s/$data/$MYIP/g" /etc/hosts
echo "completed"
unset MYIP
rm -rf errips
exit 0
fi
done
EOF
done
Abaixo está a saída
root@master:~# ./script
cat: errips: No such file or directory
successfully logged in 192.168.229.131
cat: errips: No such file or directory
successfully logged in 192.168.229.132
Por que o loop for após o login no servidor é executado antes do login?
Eu tentei usar o abaixo em vez de 'for'
cat errips |while read line
echo line currently has $line
Nesse caso, descobri que a linha ainda está pegando o IP do arquivo do servidor em localhost, mas deveria lê-lo no arquivo errips do servidor em que efetuei login remotamente.
A saída foi
line currently has 192.168.229.131
line currently has 192.168.229.132
enquanto eu esperava que ele lesse os valores no arquivo "errips" e a saída fosse algo como abaixo
line currently has 192.168.229.151
line currently has 192.168.229.151
Agora, tentei o comando abaixo
cat errips |while read data
echo data currently has $data
Neste caso, a saída estava vazia para os dados do valor
data currently has
data currently has
Como eu leria o arquivo "errips" no meu servidor remoto linha por linha, e grep para a linha em /etc/hosts e então executaria o loop if, que substituirá o ip errado pelo ip correto?
Responder1
Você precisa colocar aspas simples na string de limite do documento aqui, caso contrário, a substituição de parâmetros será habilitada. Isso deve funcionar:
#!/bin/bash
cat server | while read line
do
/usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@$line <<'EOF'
echo successfully logged in $line
MYIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
for i in 151 152
do
echo 192.168.229.$i >> errips
done
for data in `cat errips`
do
echo data currently has $data
grep $data /etc/hosts
if [ $? -eq 0 ]
then
sed -i "s/$data/$MYIP/g" /etc/hosts
echo "completed"
unset MYIP
rm -rf errips
exit 0
fi
done
EOF
done
Observe as aspas simples em torno de EOF. Para esclarecer ainda mais, tente o seguinte:
/usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@<your_ip> 'k=1; echo $k'
/usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@<your_ip> "k=1; echo $k"
/usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@<your_ip> "k=1; echo \$k"