Shell编程中while与for的区别及用法详解【转】

Stella981
• 阅读 455

在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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Shell编程之while&until循环详解
循环语句命令常用于执行一条指令或者一组指令,那么直到条件不在满足时停止,在shell脚本中循环语句常见有whileuntilforselect循环语句。在while循环语句主要用来重复执行一组命令或语句,在企业实际应用中,常用于守护进程持续运行的程序。1、在这么多语句中,while循环有它的语法格式,如下:
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这