Chinaunix首页 | 论坛 | 博客
  • 博客访问: 750158
  • 博文数量: 231
  • 博客积分: 3217
  • 博客等级: 中校
  • 技术积分: 2053
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-04 12:01
文章分类

全部博文(231)

文章存档

2015年(1)

2013年(10)

2012年(92)

2011年(128)

分类: LINUX

2012-09-11 18:28:14

一个shell脚本:
config=/usr/config.ini
...
while read server ip
...
done < $config

while循环结构如下:
while 条件
do
...
done

应该前面还有个do的。这是固定结构,满足条件就会一直循环下去。

因为最后有输入重定向符号<,将整个while循环条件的输入指定为config变量定义的文件。所以,read会逐行读取这个文件中的字段(每行两个字段)分别作为server和ip。 
需要注意的是,config.ini文件中的标题行也会被读入。 

man read,说明中可以看到,如果读成功的话,read返回读取的字节数;读到文件的末尾则返回0。而对于while来讲,条件为0表示为false,则退出循环。


 有个需求:有三列信息文本,第一列IP,第二列用途,第三列备注,需要登录每个IP执行命令,不符合执行命令结果的,打印出文本中这一行信息。 
   需求很简单,只要用一个循环,能逐一登录到每台机器,执行命令就可以了,刚开始以为只要5分钟就能搞定的事情,结果花费了我一个上午的时间。主要耽搁在while循环里面嵌套了ssh。 
   首先说说for跟while读行的区别,如都只有一列,结果是一样的,但是如果多列,比如txt内容这样: 
line1 line2  line2 
line4  line5  line6 
用for循环: 
for line in `cat txt`; 
do echo $line; 
done 
显示的结果: 
line1
line2
lien3
line4 
line5 
line6 
用while循环: 
cat txt|while read line; 
do echo $line; 
done 
显示的结果: 


line1 line2  line2 
line4  line5  line6 
   因此我的需求能用while来做,脚本如下: 
cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh -o ConnectTimeout=10 ${IP} "ls -l /home/admin|grep /"keyword/""
    if [ ! $? == "0" ];then
        echo "$line"
     fi
done 
   但是问题来了,执行后,只做了一行就结束了,刚开始还怀疑难道是if判断有问题,一个if结束就退出来了,于是在脚本的每一步都加了调试信息,结果很快发 现并不是if结束就退出来了。于是就逐个注释掉调试,发现把ssh这句注释了就能继续下去,难道ssh哪里写错了?原因不是这样的。后来在网上查了资料, 发现这么一句话:while中使用重定向机制。也就是说一开始做while循环,txt全部内容已经被重定向给while循环,而ssh语句正好会读取输入中的所有东西。于是自己调试一下: 
    
  cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh ${IP} "cat"
done 
  显示结果: 
line4  line5  line6 
也就是是说,最后一行已经读完了,循环也就结束了。 
解决办法:将ssh的输入重定向输入。 
  
cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh -o ConnectTimeout=10 ${IP} "ls -l /home/admin|grep /"keyword/""     if [ ! $? == "0" ];then
        echo "$line"
     fi
done 
ssh最后加上  
while read line
do
ehco "hello"
done < file

阅读(4037) | 评论(0) | 转发(1) |
0

上一篇:shell中re表达式

下一篇:线性表和链表

给主人留下些什么吧!~~