linux while 循环加sleep,51CTO博客-专业IT技术博客创作平台-技术成就梦想

前文中介绍的for循环,在使用时必须先建立一个元素列表,以决定循环的次数,但是考虑下面这个例子:如果用户输入“quit”就退出程序,否则将用户输入的字符转换为大写,如and转换为AND,exit转换为EXIT。这个例子无法建立元素列表,因为无法确定用户何时输入quit,也就无法确定要循环多少次。要解决这个问题,就需要引入一个新的机制:while和until。while和until尤其适合循环次数未知的情况,当然,对于循环次数已知的情况,它们也同样适用。

一、while的使用方法

while的基本格式为:

while测试条件; do

语句1

语句2

...

done

它的意思是当条件满足时,就执行循环,直到条件不满足,就退出循环。它和if的用法有些相似,只不过if只执行一次,而while会对条件反复测试,反复执行,直到条件不满足为止。那么如何使条件不满足呢?这就需要在循环体中改变初始的测试条件中相应变量的值,如果不改变,那么就会形成死循环。

二、while循环的实例演示

例1.现在使用while循环来计算100以内所有正整数的和:

[root@localhost tutor]# vimsum_while.sh#!/bin/bash

Sum=0

Count=1

while [ $Count -le 100 ]; do

Sum=$[$Sum+$Count]

let Count++

done

echo $Sum

[root@localhost tutor]# bashsum_while.sh5050

例2.计算100以内所有偶数的和;

[root@localhost tutor]# vimeven_sum_while.sh#!/bin/bash

EvenSum=0

Count=0

while [ $Count -le 100 ]; do

letEvenSum+=Count

let Count+=2

# 使用+=可以表示自身加上一个数

done

echo $EvenSum

[root@localhost tutor]# basheven_sum_while.sh2550

这个程序还可以写成以下形式:

[root@localhost tutor]# vimeven_sum_while.sh#!/bin/bash

EvenSum=0

Count=0

while [ $Count -le 100 ];do

if [$[$Count%2] -eq 0 ];then

letEvenSum+=$Count

fi

let Count++

done

echo $EvenSum

# 虽然这种写法较前一种方法看起来更复杂,但它的扩展性更好,比如可以做任意奇数的和,3倍数的和等等

[root@localhost tutor]# basheven_sum_while.sh2550

如果要遍历文件中的每一行,可以使用while循环配合输入重定向的方式,在done后面重定向要读取的文件,其用法如下:

whileread LINE; do

statement1

statement2

...

done< /Path/To/Somefile

例3.如果用户的ID号为偶数,则显示其名称和shell;对所有用户执行此操作:

[root@localhost tutor]# vimread_line.sh#!/bin/bash

while read LINE; do

# 这里的read LINE表示读取/etc/passwd这个文件的一行,将读到的内容放进LINE这个变量中

Uid=`echo$LINE | cut -d: -f3`

if [ $[$Uid%2]-eq 0 ]; then

echo$LINE | cut -d: -f1,7

fi

done 

[root@localhost tutor]# bashread_line.shroot:/bin/bash

daemon:/sbin/nologin

lp:/sbin/nologin

shutdown:/sbin/shutdown

mail:/sbin/nologin

uucp:/sbin/nologin

games:/sbin/nologin

ftp:/sbin/nologin

rpc:/sbin/nologin

avahi-autoipd:/sbin/nologin

nfsnobody:/sbin/nologin

haldaemon:/sbin/nologin

gdm:/sbin/nologin

ntp:/sbin/nologin

apache:/sbin/nologin

saslauth:/sbin/nologin

sshd:/sbin/nologin

tcpdump:/sbin/nologin

user1:/bin/bash

user3:/bin/bash

user5:/bin/bash

user7:/bin/bash

user9:/bin/bash

hello:/bin/tcsh

hadoop:/bin/bash

例4:转换用户输入的字符为大写,除了quit(遇见quit退出):

[root@localhost tutor]# vimquit_by_user.sh#!/bin/bash

read -p "A string: " String

while [ "$String" != 'quit' ]; do

echo $String |tr 'a-z' 'A-Z'

read -p"Next [quit for exit]: " String

done

[root@localhost tutor]# bashquit_by_user.shA string: sd gfdg

SD GFDG

Next [quit for exit]: adf!fdsf@

ADF!FDSF@

Next [quit for exit]: exit

EXIT

Next [quit for exit]: quit

[root@localhost tutor]#

例5、使用while循环统计/etc/rc.d/init.d/functions中#开头的行数;

[root@localhost tutor]# vimnum_lines_while.sh#!/bin/bash

Num=0

while read LINE; do

echo $LINE |grep "^[[:space:]]*#" &> /dev/null && let Num++

# 考虑以#开头的,并且考虑以空格和#开头的行

# 使用&&可以代替if

done 

echo "Total $Num lines start with #."

[root@localhost tutor]# bashnum_lines_while.shTotal 70 lines start with #.

三、until循环的使用方法

until和while循环很类似,都是当循环次数未知的时候使用。until的用法格式如下:

until测试条件; do

语句1

语句2

...

done

和while相反,until是当条件满足时,退出循环;而当条件不满足时就执行语句。事实上until和while二者可以互换,当对满足while的条件取反时,就是until。

四、until循环的实例演示

例6.使用until改写例1,计算100以内所有正整数的和:

[root@localhost tutor]# vimsum_until.sh#!/bin/bash

Sum=0

Count=1

until [ $Count -gt 100 ]; do

# while中使用的是le,until和while的条件相反

letSum+=$Count

let Count++

done

echo $Sum

[root@localhost tutor]# bashsum_until.sh

5050

例7.计算100以内所有偶数的和以及奇数的和;在一个循环中实现;

[root@localhost tutor]# vimuntil_odd_even.sh#!/bin/bash

SumOdd=0

SumEven=0

i=1

until [ $i -gt 100 ];do

if [ $[$i%2]-eq 0 ];then

letSumOdd+=$i

else

letSumEven+=$i

fi

let i++

done

echo " Odd Sum: $SumOdd. Even Sum: $SumEven"

[root@localhost tutor]# bashuntil_odd_even.shOdd Sum: 2550. EvenSum: 2500

例8.使用until改写例4,转换用户输入的字符为大写,除了quit(遇见quit退出):

[root@localhost tutor]# vimquit_until.sh#!/bin/bash

read -p "A String: " String

until [ "$String" == 'quit' ]; do

# while循环中当$String不等于quit时执行,until与之相反

echo $String |tr 'a-z' 'A-Z'

read -p"Next [quit for Exit]: " String

done

[root@localhost tutor]# bashquit_until.shA String: sdf opq

SDF OPQ

Next [quit for Exit]: 123#fsd

123#FSD

Next [quit for Exit]: Quit

QUIT

Next [quit for Exit]: quit

例9、每隔5秒查看hadoop用户是否登录,如果登录,显示其登录并退出;否则,显示当前时间,并说明hadoop尚未登录:

这里需要引入一个新命令sleep,这个命令表示休眠,后面的参数接秒数

[root@localhost tutor]# mansleep

SLEEP(1)          UserCommands            SLEEP(1)

NAME

sleep - delayfor a specified amount of time

SYNOPSIS

sleep NUMBER[SUFFIX]...

如果要确定当前登陆的用户,可以使用who命令,而要确定hadoop用户是否登陆了,可以使用grep命令:

[root@localhost tutor]# vimhadoop_login.sh#!/bin/bash

until who | grep "^hadoop" &> /dev/null; do

# 使用who命令可以查看当前登陆的用户

# 由于who是个命令,而不是一个表达式,所以不需要[]

date

sleep 5

done

echo "Welcom back, hadoop!"

为了更好的理解上述程序的逻辑,可以将其改写为:

[root@localhost tutor]# vimhadoop_login.sh#!/bin/bash

who | grep "^hadoop" &> /dev/null

RetVal=$?

# 先执行一次 who 和 grep命令

# 然后取出执行状态返回值

until [ $RetVal-eq 0 ]; do

# 如果执行状态返回值为0,表示who和grep命令执行成功了,就停止执行循环体

date

sleep 5

who | grep"^hadoop" &> /dev/null

Retval=$?

# 如果date和sleep命令执行了,就再执行一次who和grep命令,以检查hadoop用户是否登陆

done

echo "Welcomback, hadoop!"

[root@localhost tutor]# bashhadoop_login.shSat Aug 16 09:55:37 EDT 2014

Sat Aug 16 09:55:42 EDT 2014

Sat Aug 16 09:55:47 EDT 2014

# 此时开启另一个终端,用Hadoop用户登陆

Welcom back, hadoop!

例10.写一个脚本:

1)显示一个菜单给用户:

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

*) quit.

2)当用户给定选项后显示相应的内容;

当用户选择完成,显示相应信息后,不退出;而让用户再一次选择,再次显示相应内容;除了用户使用quit;

[root@localhost tutor]# vimshow_disk.sh#!/bin/bash

cat <

d|D) show disk usages.

m|M) show memery usages.

s|S) show swap usages.

quit) quit

EOF

read -p "Input your choice [quit means exit]: "Char

until [ "$Char" == 'quit' ]; do

case $Char in

d|D)

df -lh

;;

m|M)

free -m |grep "^Me"

;;

s|S)

free -m |grep "^Sw"

;;

*)

echo"Input Errors."

;;

esac

read -p"Input your choice [quit means exit]:" Char

done

[root@localhost tutor]# bashshow_disk.shd|D) show disk usages.

m|M) show memery usages.

s|S) show swap usages.

quit) quit

Input your choice [quit means exit]: d

Filesystem                   Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root   23G 4.6G   17G  22% /

tmpfs                        499M  112K  499M  1% /dev/shm

/dev/sda1                    485M   35M  426M  8% /boot

/dev/sdb3                    9.9G   36M  9.7G  1% /mydata

Input your choice [quit means exit]:M

Mem:          996        358        638          0         63        114

Input your choice [quit means exit]:s

Swap:        3051          0       3051

Input your choice [quit means exit]:a

Input Errors.

Input your choice [quit means exit]:quit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值