IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

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

运维派 2015-04-08 00:01:25 累计浏览 8,188 次
本机暂存

   如果要使用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. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. Linux如何统计进程的CPU利用率 (累计阅读 16,307)
  2. 我的 RHCA 之路 (累计阅读 14,011)
  3. Linux内存点滴 用户进程内存空间 (累计阅读 13,228)
  4. 给程序员新手的一些建议 (累计阅读 13,088)
  5. Linux 性能监控、测试、优化工具 (累计阅读 13,010)
  6. 关于linux内存free的一些事情 (累计阅读 12,866)
  7. 高效Linux用户需要了解的命令行技能 (累计阅读 12,823)
  8. ps - 按进程消耗内存多少排序 (累计阅读 12,685)
  9. Google怎么用linux (累计阅读 12,580)
  10. Linux Used内存到底哪里去了? (累计阅读 11,866)