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

前文中介绍的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以内所有正整数的和

[[email protected] tutor]# vimsum_while.sh

#!/bin/bash
Sum=0
Count=1
while [ $Count -le 100 ]; do
       Sum=$[$Sum+$Count]
        let Count++
done
echo $Sum

[[email protected] tutor]# bashsum_while.sh

5050

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

[[email protected] tutor]# vimeven_sum_while.sh

#!/bin/bash
EvenSum=0
Count=0
 
while [ $Count -le 100 ]; do
        letEvenSum+=Count
        let Count+=2
# 使用+=可以表示自身加上一个数
done
echo $EvenSum

[[email protected] tutor]# basheven_sum_while.sh

2550

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

[[email protected] 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倍数的和等等

[[email protected] tutor]# basheven_sum_while.sh

2550

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

            whileread LINE; do

              statement1

              statement2

              ...

            done< /Path/To/Somefile

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

[[email protected] 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

[[email protected] 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退出):

[[email protected] 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

[[email protected] tutor]# bashquit_by_user.sh

A string: sd gfdg
SD GFDG
Next [quit for exit]: [email protected]
[email protected]
Next [quit for exit]: exit
EXIT
Next [quit for exit]: quit
[[email protected] tutor]#

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

[[email protected] 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 #."

[[email protected] 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以内所有正整数的和

[[email protected] 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

[[email protected] tutor]# bashsum_until.sh

5050

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

[[email protected] 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

[[email protected] 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

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

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

[[email protected] tutor]# mansleep

SLEEP(1)          UserCommands            SLEEP(1)

NAME

sleep - delayfor a specified amount of time

SYNOPSIS

sleep NUMBER[SUFFIX]...

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

[[email protected] tutor]# vimhadoop_login.sh

#!/bin/bash
until who | grep "^hadoop" &> /dev/null; do
# 使用who命令可以查看当前登陆的用户
# 由于who是个命令,而不是一个表达式,所以不需要[]
        date
        sleep 5
done
 
echo "Welcom back, hadoop!"

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

[[email protected] 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!"

[[email protected] 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!
时间: 2024-08-01 06:45:52

28_Shell语言——while和until循环(while, until, sleep)的相关文章

13_Shell语言———语言控制结构之for循环语句

一.语言控制结构概述 在前文中(4_Shell语言---脚本概述)介绍过面向过程的编译语言,其控制结构主要有以下三种: a) 顺序执行:默认法则:一句一句逐行执行: b) 选择执行:进行条件判断,只有部分是符合条件的,故只执行符合条件的部分: 条件判断通常采用布尔测试:即判断条件为真或为假,在bash中: 0: 为真 1~255: 为假(即非0为假,这点和很多编程语言相反) c) 循环执行:将同一段代码反复执行N次,若N为无穷大,则会出现死循环的现象,故循环必须有退出条件,这里的N就是退出条件.

C语言优化实例:循环中减少判断

为了让编译器更好地优化循环,应该尽量让循环中减少判断,方法之一是将判断语句整合进表达式.还是这个例子: for (int i = 0; i < 1000*10; i++) { sum += data[i/1000][i%10]; } 假如我们需要加一个判断,只有非负整数才需要作求和运算: for (int i = 0; i < 1000*10; i++) { if (data[i/1000][i%10] >= 0) sum += data[i/1000][i%10]; } 下面将这个判断

Java语言程序设计基础篇 循环(四)

①打印:***** **** *** ** * for(int x=1; x<=5; x++) { for(int y=x; y<=5; y++) { System.out.print("*"); //向下一般的格式for(int y=x; y<=5; y++) } System.out.println(); } ②打印:* ** *** **** ***** for (int x=1; x<=5 ;x++ ) { for (int y=1;y<=x ;y

Java语言程序设计基础篇 循环(四)练习

*4.21(计算不同利率下的贷款)编写程序,让用户输入贷款总额及以年为单位的贷款期限,以1/8为递增量,显示从5%到8%的利率下每月支付额和总偿还额.假设输入贷款总量为10 000,还贷期限为5年,所显示的输出如下: 贷款总额:to 000 年数:5 利率月支付额总偿还额 5%188 .71   11322.74 5 .125%189.28   11357.13 5 .25%189.85   11391.59 ... //Exercise3_26.java: displays the month

C语言实现按位循环左移和循环右移

ror eax,cl ==> eax=(eax>>cl)+(eax<<(sizeof(eax)-cl)); rol eax,cl ==> eax=(eax<<cl)+(eax>>(sizeof(eax)-cl)); C语言实现按位循环左移和循环右移

Java语言中的----条件循环

day06 Java语言中的条件循环 一.条件循环概述: 条件循环对于我们来说一点也不陌生,在程序中使用循环语句是很普片的事儿,所以说你一定得学会循环语句. 二.条件循环 条件循环主要包括两个循环语句,分别是if...else和switch...case语句. 1.if循环结构         if (){                  }else{                  } 2.switch...case循环结构         switch () {     case 1:

C语言的基本结构——循环结构

  今天我们计算机协会的社长给我说让我去给小学弟小学妹们讲一次C语言入门,他们老师已经讲过前面我们写过的博文了,我打算给他们讲一下C语言的基本结构--循环,判断,分支.  今天我们就着重说说循环结构.  循环结构分为三种,分别是for.while.dowhile;  我们首先说第一种:for循环..他的代码格式为: for(判断的数值初始化;判断条件;改变判断数值大小){ 循环语句块: }   我们举个例子,我们以输出1~10的数字为例: #include<stdio.h> int main(

C语言第4天循环,流程控制。

C语言第四天 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; max-width: 100%; height: auto !important; margin: 2px 0; } table { border-collapse: collapse; border: 1px solid #bbbbbb; } td, th { padding: 4px 8p

C语言基础知识【循环】

C 循环1.有的时候,我们可能需要多次执行同一块代码.一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推.编程语言提供了更为复杂执行路径的多种控制结构.循环语句允许我们多次执行一个语句或语句组,2.循环类型C 语言提供了以下几种循环类型.点击链接查看每个类型的细节.循环类型    描述while 循环    当给定条件为真时,重复语句或语句组.它会在执行循环主体之前测试条件.for 循环    多次执行一个语句序列,简化管理循环变量的代码.do...while