Shell编程中while与for的区别及用法详解
在shell编程中经常用到循环,常用的循环有for和while循环两种。while循环默认以行读取文件,而for循环以空格读取文件切分文件,本篇就结合现网的一些使用示例说说二者的用法和区别。
一、常用语法
1、for循环
for循环常用的语法结构有如下几种:
for变量inseq字符串
for变量in`command`""
for变量in"$@"或“$*”
for((赋值;条件;运算语句))
2、while循环
while循环常用的语法结构有如下几种:
while[$i-ltnum] whiletrue whilereadabc;docommanddone<filename catfilename|whilereadabc
二、行读取示例
这里以常见的df获取磁盘信息为例,了解下使用for和while的几种循环方法处理时的区别。先看下我写的脚本,内容如下:
#/bin/bash ##author:yangbk ##site:www.361way.com ##mail:itybku@139.com ##desc:testloopforinandwhile df-hl|awk'int($5)>30'>testfile result=`df-hl|awk'int($5)>30'` echo'*******************fortesting*****************' foriin$result;do echo$i done echo'*******************whileechotest*************' echo$result|whilereadline do echo$line done echo'******************whiletesting****************' df-hl|awk'int($5)>30'|whilereadline do echo$IP`hostname`$line done echo'******************whilereadfile**************' whilereadline do echo$IP`hostname`$line done<testfile
上面的脚本执行时结果如下:
#shforwhile.sh *******************fortesting***************** /dev/sda3 9.5G 5.7G 3.4G 64% / /dev/sda2 39G 19G 18G 52% /home /dev/sda6 9.5G 7.1G 2.0G 78% /usr *******************whileechotest************* /dev/sda39.5G5.7G3.4G64%//dev/sda239G19G18G52%/home/dev/sda69.5G7.1G2.0G78%/usr ******************whiletesting**************** localhost/dev/sda39.5G5.7G3.4G64%/ localhost/dev/sda239G19G18G52%/home localhost/dev/sda69.5G7.1G2.0G78%/usr ******************whilereadfile************** localhost/dev/sda39.5G5.7G3.4G64%/ localhost/dev/sda239G19G18G52%/home localhost/dev/sda69.5G7.1G2.0G78%/usr
可以看到,只有后面两种方法可以正常获取到我们想要的数据,前面两种方法在处理时和我们想要的结果都不一样。此示例得出的结果为:
1、while循环:以行读取文件,默认分隔符是空格或者Tab;
2、for循环:以空格读取文件,也就是碰到空格,就开始执行循环体,所以需要以行读取的话,就要把空格转换成其他字符。
三、ssh连接与wait
这里还是以一个测试脚本为例:
#!/bin/bash ##author:yangbk ##site:www.361way.com ##mail:itybku@139.com ##desc:testwaitandsshwhenuseforinandwhile #whileloop echo-en"\t";date catabc.txt|whilereaduserip do { ssh-oConnectTimeout=10$user@$ip"hostname"</dev/null sleep10s }& done wait echo"Thisiswhileloop." echo-en"\t";date sleep10s echo-e"\n" #forloop echo-en"\t";date forlinein`catabc.txt|sed-e's//--/g'` do { user=`echo$line|awk-F'--''{print$1}'` ip=`echo$line|awk-F'--''{print$2}'` ssh-oConnectTimeout=10$user@$ip"hostname" sleep10s }& done wait echo"Thisisforloop." echo-en"\t";date
此示例的结果这里不再输出,具体可以使用该脚本ssh几台主机做个测试,测试后得到结果如下:
1、for循环:循环体在后台执行,等待循环体全部执行结束,后面的命令接着执行。
2、while循环:wait没起到作用,循环体在后台执行,后面的命令也同时在执行。循环体内有ssh、scp、sshpass的时候有执行一次循环就退出的情况,解决该问题方法有如下两种:
a、使用ssh-n"command";
b、将while循环内加入null重定向,如ssh"cmd"</dev/null将ssh的输入重定向输入。
四、执行效率
在对大文件进行按行读取(for在读取文件时,可以foriin`catfilename`进行按行读取)的效率方面,经测试while要更快一些。
shell:for和while用法
写法一:
----------------------------------------------------------------------------
#!/bin/bash
whilereadline
do
echo$line
done<file(待读取的文件)
----------------------------------------------------------------------------
写法二:(并发脚本慎用,grep不能输出全部匹配的信息)
----------------------------------------------------------------------------
#!/bin/bash
catfile(待读取的文件)|whilereadline
do
echo$line
done
----------------------------------------------------------------------------
写法三:
----------------------------------------------------------------------------
forlinein`catfile(待读取的文件)`
do
echo$line
done
----------------------------------------------------------------------------
说明:
for逐行读和while逐行读是有区别的,如:
$catfile aaaa bbbbfffggg ccccdddd $catfile|whilereadline;doecho$line;done aaaa bbbbfffggg ccccdddd $forlinein$(<file);doecho$line;done aaaa bbbb fff ggg cccc dddd