在shell编程中经常用到循环,常用的循环有for和while循环两种。while循环默认以行读取文件,而for循环以空格读取文件切分文件,本篇就结合现网的一些使用示例说说二者的用法和区别。

一、常用语法

1、for循环

for循环常用的语法结构有如下几种:

for 变量 in seq字符串
for 变量 in `command` " "
for 变量 in "$@"或“$*”
for((赋值;条件;运算语句))

2、while循环

while循环常用的语法结构有如下几种:

1
2
3
4
while [ $i -lt num ]
while true
while read a b c; do command done < filename
cat filename | while read a b c

二、行读取示例

这里以常见的df获取磁盘信息为例,了解下使用for和while的几种循环方法处理时的区别。先看下我写的脚本,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#/bin/bash
## author: yangbk
## site: www.361way.com
## mail: itybku@139.com
## desc: test loop for in and while
df -hl|awk 'int($5) >30 ' > testfile
result=`df -hl|awk 'int($5) >30 '`
echo '******************* for testing *****************'
for i in $result;do
echo $i
done
echo '******************* while echo test *************'
echo $result | while read line
do
echo $line
done
echo '****************** while testing ****************'
df -hl|awk 'int($5) >30 '|while read line
do
echo $IP `hostname` $line
done
echo '****************** while read file **************'
while read line
do
echo $IP `hostname` $line
done < testfile

上面的脚本执行时结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# sh forwhile.sh
******************* for testing *****************
/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
******************* while echo test *************
/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
****************** while testing ****************
localhost /dev/sda3 9.5G 5.7G 3.4G 64% /
localhost /dev/sda2 39G 19G 18G 52% /home
localhost /dev/sda6 9.5G 7.1G 2.0G 78% /usr
****************** while read file **************
localhost /dev/sda3 9.5G 5.7G 3.4G 64% /
localhost /dev/sda2 39G 19G 18G 52% /home
localhost /dev/sda6 9.5G 7.1G 2.0G 78% /usr

可以看到,只有后面两种方法可以正常获取到我们想要的数据,前面两种方法在处理时和我们想要的结果都不一样。此示例得出的结果为:

1、while循环: 以行读取文件,默认分隔符是空格或者Tab;

2、for循环: 以空格读取文件,也就是碰到空格,就开始执行循环体,所以需要以行读取的话,就要把空格转换成其他字符。

三、ssh连接与wait

这里还是以一个测试脚本为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
## author: yangbk
## site: www.361way.com
## mail: itybku@139.com
## desc: test wait and ssh when use for in and while
# while loop
echo -en "\t";date
cat abc.txt|while read user ip
do
{
ssh -o ConnectTimeout=10 $user@$ip "hostname" < /dev/null
sleep 10s
} &
done
wait
echo "This is while loop."
echo -en "\t";date
sleep 10s
echo -e "\n"
# for loop
echo -en "\t";date
for line in `cat abc.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"
sleep 10s
} &
done
wait
echo "This is for loop."
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在读取文件时,可以for i in `cat filename`进行按行读取)的效率方面,经测试while 要更快一些。

shell:for和while用法

写法一:

----------------------------------------------------------------------------
#!/bin/bash

while read line
do
echo $line
done < file(待读取的文件)
----------------------------------------------------------------------------

写法二:(并发脚本慎用,grep不能输出全部匹配的信息)
----------------------------------------------------------------------------
#!/bin/bash

cat file(待读取的文件) | while read line
do
echo $line
done
----------------------------------------------------------------------------

写法三:

----------------------------------------------------------------------------
for line in `cat file(待读取的文件)`
do
echo $line
done
----------------------------------------------------------------------------

说明:

for逐行读和while逐行读是有区别的,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat file
aaaa
bbbb fff ggg
cccc dddd
$ cat file | while read line; do echo $line; done
aaaa
bbbb fff ggg
cccc dddd
$ for line in $(<file); do echo $line; done
aaaa
bbbb
fff
ggg
cccc
dddd

Shell编程中while与for的区别及用法详解【转】的更多相关文章

  1. PHP版本的区别与用法详解

    在我们安装PHP模块时,有时需要注意PHP编译的版本,下面讲解下PHP中VC6.VC9.TS.NTS版本的区别与用法详解,介绍php的两种执行方式. 1. VC6与VC9的区别:VC6版本是使用Vis ...

  2. Python中第三方库Requests库的高级用法详解

    Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...

  3. JavaScript中return的用法和this的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对this和函数中的return的用法和意思理解的比较模糊,这里写一篇博客跟大家一起探讨一下return和this的 ...

  4. shell脚本中常见的一些特殊符号和作用详解

    这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下   在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...

  5. PHP中VC6、VC9、TS、NTS版本的区别与用法详解

    Thread safe(线程安全)是运行在Apache上以模块的PHP上,如果你以CGI的模式运行PHP,请选择非线程安全模式(non-thread safe). 1. VC6与VC9的区别: VC6 ...

  6. SQL学习笔记之SQL中INNER、LEFT、RIGHT JOIN的区别和用法详解

    0x00 建表准备 相信很多人在刚开始使用数据库的INNER JOIN.LEFT JOIN和RIGHT JOIN时,都不太能明确区分和正确使用这三种JOIN操作,本文通过一个简单的例子通俗易懂的讲解这 ...

  7. js中 call() 和 apply() 方法的区别和用法详解

    1.定义 每个函数都包含俩个非继承而来的方法:call() 和 apply()   call 和 apply 可以用来重新定义函数的的执行环境,也就是 this 的指向:call 和 apply 都是 ...

  8. JavaScript中bind、call、apply函数用法详解

    在给我们项目组的其他程序介绍 js 的时候,我准备了很多的内容,但看起来效果不大,果然光讲还是不行的,必须动手.前几天有人问我关于代码里 call() 函数的用法,我让他去看书,这里推荐用js 写服务 ...

  9. php部分---include()与require()的区别、empty()与isset is_null的区别与用法详解

    include()与require()的用途是完全一样的,不一定非得哪个放在最前面哪个放在中间.他们最根本的区别在于错误处理的方式不一样. 1.处理错误的方式: require()一个文件存在错误的话 ...

随机推荐

  1. python第三次周末大作业

    ''' s18第三周周末⼤作业 模拟博客园系统: 1. 启动程序, 显⽰菜单列表 菜单: 1. 登录 2. 注册 3. ⽂章 4. ⽇记 5. 退出 2. ⽤户输入选项, ⽂章和⽇记必须在登录后才可以 ...

  2. Kafka技术内幕 读书笔记之(五) 协调者——协调者处理请求

    消费者客户端使用“消费者的协调者对象”( ConsumerCoordinator )来代表所有和服务端协调者节点有关的请求处理,比如心跳请求.获取和提交分区的偏移量(自动提交任务).发送“加入组请求” ...

  3. windows安装mysql5.7.xx解压版

    解压后修改配置文件 my.ini [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] #设置3306端口 port = 3306 ...

  4. hihoCoder #1457 : 后缀自动机四·重复旋律7(后缀自动机 + 拓扑排序)

    http://hihocoder.com/problemset/problem/1457 val[i] 表示状态i所表示的所有字符串的十进制之和 ans= ∑ val[i]在后缀自动机上,从起始状态走 ...

  5. 自学python 4.

    1.li = ["alex","tom","mike","god","merffy"](1)a = ...

  6. 多线程Thread类的方法

    创建多个线程的第一种方法 1.定义一个Thread类的子类,比如MyThread类 2.重写Thread的run方法,设置线程任务 3.创建Mythread类的对象 4.调用方法start(),开启新 ...

  7. 【转载】C# 获取系统时间及时间格式

    https://www.cnblogs.com/xjtrab/articles/1878353.html

  8. 【转载】 C#读写注册表

    文章地址:https://blog.csdn.net/younghaiqing/article/details/61918968 自Windows95以来的所有Windows版本中,注册表是包含Win ...

  9. 实惠VPS推荐

    1. Topmain 2. Virmach 3. BanwagonHost  [备用地址1] [备用地址2] 4. HiFormance  (跑路) 5. my.hosteons.com 6. . 以 ...

  10. ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树

    五.KMP算法:    *KMP算法是一种改进的字符串匹配算法.    *KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一个next()函 ...