чтение файла с использованием for, while - поведение

чтение файла с использованием for, while - поведение

Рассмотрим следующий сценарий.

2 ВМ - 192.168.229.131, 192.168.229.132

/etc/hostsУ обеих виртуальных машин в файле есть IP-адреса 192.168.229.151 и 192.168.229.152.

Допустим, есть около 50 виртуальных машин, как я сказал выше. Но на данный момент я рассматриваю только 2 из них.

Я сохранил IP-адреса двух виртуальных машин в файле с именем server.

#cat server
192.168.229.131
192.168.229.132

Ниже представлен сценарий

#!/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

Ниже представлен вывод

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

Почему цикл for после входа на сервер выполняется до входа в систему?

Я попробовал использовать нижеследующее вместо «for»

cat errips |while read line
echo line currently has $line

В этом случае я обнаружил, что строка по-прежнему берет IP-адрес из файла сервера на локальном хосте, тогда как она должна считывать его из файла errips сервера, на который я удаленно вошел.

Выход был

line currently has 192.168.229.131
line currently has 192.168.229.132

тогда как я ожидал, что он должен прочитать значения в файле "errips", а вывод должен быть примерно таким:

line currently has 192.168.229.151
line currently has 192.168.229.151

Теперь я попробовал следующую команду

cat errips |while read data
echo data currently has $data

В этом случае вывод был пустым для данных значения

data currently has 
data currently has

Как мне прочитать файл «errips» на моем удаленном сервере построчно и выполнить grep для поиска строки в /etc/hosts, а затем выполнить цикл if, который заменит неправильный IP на правильный?

решение1

Вам нужно заключить в одинарные кавычки строку ограничения документа here, иначе будет включена подстановка параметров. Это должно сработать:

#!/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

Обратите внимание на одинарные кавычки вокруг EOF. Чтобы прояснить ситуацию, попробуйте следующее:

/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"

Связанный контент