设为首页 收藏本站
查看: 1023|回复: 0

28_Shell语言——while和until循环(while, until, sleep)

[复制链接]

尚未签到

发表于 2018-8-19 10:47:46 | 显示全部楼层 |阅读模式
  前文中介绍的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.sh
5050  例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.sh
2550  这个程序还可以写成以下形式:
  [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.sh
2550  如果要遍历文件中的每一行,可以使用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 < /etc/passwd
  [root@localhost tutor]# bashread_line.sh
root:/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.sh
A 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 < /etc/rc.d/init.d/functions
  
echo "Total $Num lines start with #."
  [root@localhost tutor]# bashnum_lines_while.sh
Total 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.sh
Odd 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.sh
A 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.sh
Sat 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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-553779-1-1.html 上篇帖子: ORACLE 将SQL的执行脚本返回值传给SHELL-Be the miracle! 下篇帖子: shell写自动安装脚本自动读取license和自动输入回车
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表