使用 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个。

我将 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 替换错误的 ip?

答案1

您需要单引号您的此处文档限制字符串,否则将启用参数替换。这应该有效:

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

相关内容