IT技术博客大学习 共学习 共进步

Linux shell脚本使用while循环执行ssh的注意事项

运维派 2015-04-08 00:01:25 浏览 8,063 次

   如果要使用ssh批量登录到其它系统上操作时,我们会采用循环的方式去处理,那么这里存在一个巨大坑,你必须要小心了。

   一、场景还原:

   我现在是想用一个脚本获取一定列表服务器的运行时间,首先我建立一个名字为ip.txt的IP列表(一个IP一行),再建好密钥实现不用密码直接登录。然后写脚本如下:

#!/bin/bash
while read ips;
do
    echo $ips;
done < ip.txt

   脚本实现了逐行读取列表中的IP,但是:

#!/bin/bash
while read ips;
do
    echo $ips;
    upt=`ssh root@$ips "uptime"`;
    echo $upt;
done < ip.txt

   脚本只对第一个IP做了检测,就直接跳出来了。

   二、问题分析:

   while使用重定向机制,ip.txt文件中的信息都已经读入并重定向给了整个while语句,所以当我们在while循环中再一次调用read语句,就会读取到下一条记录。问题就出在这里,ssh语句正好回读取输入中的所有东西。为了禁止ssh读所有东西增加一个< /dev/null,将ssh 的输入重定向输入。

   三、解决策略:

   1、使用for循环代表while,因为for没有一次把文件内容缓存获取过来,代码段修改如下:

for ips in `cat ip.txt`; do
       echo ${ips};
       upt=`ssh root@${ips} uptime`;
       echo $upt;
done

   2、若坚持使用while循环,那么需要对ssh增加-n参数,为什么增加了-n参数也可以解决问题呢?通过man ssh查看-n参数的说明:

   Redirects stdin from /dev/null (actually, prevents reading from stdin)

   这就和

   修改后的代码如下:

#!/bin/bash
while read ips;
do
    echo $ips;
    upt=`ssh -n root@$ips "uptime"`;
    echo $upt;
done < ip.txt

建议继续学习

  1. 在ssh服务里使用chroot (阅读 5,841)
  2. 为什么要用公钥/私钥而不是密码去做SSH身份验证 (阅读 5,701)
  3. 如何让ssh登录更加安全 (阅读 5,604)
  4. ssh连接超时解决办法 (阅读 5,504)
  5. 懒人连ssh不输密码若干大法 (阅读 5,483)
  6. SSH无密码登录 (阅读 5,483)
  7. ssh命令 (阅读 5,225)
  8. 共享会话的ssh连接配置 (阅读 4,703)
  9. 一句话crontab实现防ssh暴力破解 (阅读 4,564)
  10. SSH下连接Oracle的方法 (阅读 4,502)