Shell脚本之条件选择与循环

前言

Bash语言是过程式编程语言,这篇文章主要讲到:条件选择、循环,这两种用法。
条件选择语句主要用到的有if,case这两种判断语句。
Shell中有3种循环,分别是for,while,until,until与while正好相反,前者条件为假则执行,后者条件为真时执行。

条件选择


if条件判断

单分支条件判断:

if 判断条件;then 
        条件为真的分支代码 
fi 

双分支条件判断:

if 判断条件; then 
    条件为真的分支代码 
else 
    条件为假的分支代码 
fi

多分支条件判断:

if 判断条件1; then 
    条件为真的分支代码 
elif 判断条件2; then 
    条件为真的分支代码 
elif 判断条件3; then 
    条件为真的分支代码 
else 
    以上条件都为假的分支代码 
fi

注:逐条件进行判断,第一次遇为“真”条件时,执行其分支, 而后结束整个if语句

下面用if条件判断语句写一个脚本来深入的理解:

#!/bin/bash
#
if ping -c1 -W2 station1 &> /dev/null; then 
    echo 'Station1 is UP' 
elif grep "station1" ~/maintenance.txt &> /dev/null 
then 
    echo 'Station1 is undergoing maintenance' 
else 
    echo 'Station1 is unexpectedly DOWN!' 
    exit 1 
fi

注:这个脚本,第一步是先判断station1是否能ping通,如果ping通了就在屏幕上打印Station1是UP状态。判断结束。
如果不能ping通就跳到下一个判断,查询~/maintenance.txt里面有没有station1,如果能查询到,则在屏幕上打印
station1 是在维护状态,半段结束。如果依然不能在在~/maintenance.txt里面查询到station1,则跳到下一步,以上
的判断都不为真,则打印station1是DOWN状态,并退出返回状态数1.


case语句
case 变量引用 in 
PAT1) 
    分支1 
    ;; 
PAT2) 
    分支2 
    ;; 
... 
*) 
默认分支 
;; 
esac

注:
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b

国际惯例,来个脚本加深理解:

#!/bin/bash
read -p 'Can I ask you out to play?(yes|no)'  go
case    $go    in
[yY]|[yY][eE][sS])
        echo "Let's go."
        ;;
[nN]|[nN][oO])
        echo "That's too bad"
        ;;
*)
        echo "Are you turning me down?"
        ;;
esac
unset go

注:case语句支持glob风格的通配符,用read来交互式输入变量$go,询问我能约你出去玩吗?这时用户输入的字符
将会被赋值到变量$go上面,如果变量go的值等于y或是Y或是yes(各种不同大小写皆可),就会打印let’s go.然后
结束,亦或是变量go的值等于n或是N或是no(各种大小写皆可),就会打印That’s too bad,然后结束。如果变
量go的值不等于上面的任何一个,就打印Are you turning me down?然后结束。


循环

基本结构

循环执行
        将某代码段重复运行多次
        重复运行多少次:
                循环次数事先已知
                循环次数事先未知
        有进入条件和退出条件
for循环

普通for循环

for 变量名 in 列表;do 
    循环体
done 

嵌套for循环

for 变量名1 in 列表1;do
    循环体1
    for 变量名2 in 列表2;do
        循环体2
    done
done

执行机制:
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体;
直到列表中的元素耗尽,循环结束

列表生成方式:

(1) 直接给出列表 
(2) 整数列表: 
    (a) {start..end} 
    (b) $(seq [start [step]] end) 
(3) 返回列表的命令 
    $(COMMAND) 
(4) 使用glob,如:*.sh 
(5) 变量引用; 
\$@, \$*

国际惯例,来个脚本。
用*打印一个等腰三角形,带闪烁带随机颜色的哦。

if [ $# = 0 ];then 
    read -p "你想打印几行的等腰三角形:" s
else
    s=$1
fi
    if [ "$s" -gt 0  ] &> /dev/null;then
        for n in `seq  $s` 
        do
        i=$[$s-$n]
        m=$[2*$n-1]
            for i in `seq  $i`; do 
                echo -n  " "
            done    
            for m in `seq  $m`; do
                color=$[$RANDOM%6+1]
                let textcolor=$color+30
                echo -en "\033[1;`echo $textcolor`;5m*\033[0;25m"
                        if [ $s -gt 10 ];then
                            sleep 0.01
                        else
                            sleep 0.05
                        fi
            done 
        echo
        done
    else 
        echo "please...给个大于零的整数吧"
    fi

注:第一步,先判断这个脚本后面是否跟了参数,如果没有,就输出 你想打印几行的等腰三角形:提示用户输入数字,
然后赋值给s(我这里为了偷懒只写了一个字母,生产中变量一定不要只写一个字母,很容易出错。),亦或是脚本后面
已经跟了参数也赋值给s,接下来判断变量s是不是大于0的整数,如果不是就输出please…给个大于零的整数吧,然后
退出。如果是大于0的整数,就进入第一个for循环,n指的是打印的第几行,i指得是这一行要打印的空白字符数,m指
的是这一行要打印的*的数量。嵌套第一个for循环,打印这一行要打印的空白字符数i个,嵌套第二个for循环,打印这
一行要打印的*的数量,里面做了随机颜色,和闪烁的特效,并用if判断语句,当行数s大于10时就以更快的速度打印。


while循环
while CONDITION; do 
        循环体 
    done 

CONDITION:循环控制条件;进入循环之前,先做一次判 断;每一次循环之后会再次做判断;条件为“true”,则执行 一次循环;直到条件测试状态为“false”终止循环

因此:CONDTION一般应该有循环控制变量;而此变量的值 会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false

while循环的特殊用法(遍历文件的每一行):

    while read line; do 
        循环体 
    done < /PATH/FROM/SOMEFILE

依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将 行赋值给变量line


until循环

until循环与while循环恰恰相反,进入条件为假,为真时就结束了。

until CONDITION; do 
    循环体 
done 

进入条件: CONDITION 为false
退出条件: CONDITION 为true


循环控制语句

continue

用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一 轮判断;
最内层为第1层

while CONDTIITON1; do 
    CMD1 
    ... 
    if CONDITION2; then 
        continue 
    fi 
    CMDn 
    ... 
done
break

用于循环体中
break [N]:提前结束第N层循环,最内层为第1层

while CONDTIITON1; do 
    CMD1 
    ... 
    if CONDITION2; then 
        break 
    fi 
    CMDn
    ... 
done
shift

循环控制shift命令
shift [n]
用于将参量列表 list 左移指定次数,缺省为左移一次。
参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift
./doit.sh a b c d e f g h
./shfit.sh a b c d e f g h

脚本详解:

while [ $# -gt 0 ] # or (( $# > 0 )) 
do 
    echo $* 
    shift 
done

注:当输入的参数大于0时不停的循环下去,比如输入的参数是aa bb cc ,那么第一次打印的就是
aa bb cc,经过shift去掉第一个参数,再次循环,打印bb cc,再经过shift,再去掉一个参数,循环,
打印cc,再经过shift去掉一个参数,此时以没有参数了,循环判断不大于0了,循环结束。

select循环与菜单
select variable in list 
    do 
        循环体命令 
    done 

select 循环主要用于创建菜单,按数字顺序排列的 菜单项将显示在标准错误上,并显示 PS3 提示符, 等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量 REPLY 中

select与case
select 是个无限循环,因此要记住用 break 命令退 出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
select 经常和 case 联合使用
与 for 循环类似,可以省略 in list,此时使用位置参量

这里放上一个我用select与case写的脚本:

PS3="please choose you menu: "
select menu in exit huimian lamian hulatang yangroutang
do
    case $menu in
    huimian)
        echo10
        ;;
    lamian)
        echo15
        ;;
    hulatang)
        echo5
        ;;
    yangroutang)
        echo20
        ;;
    exit)
        echo "真的不来一点?"
        break
        ;;
    *)
        echo "没有这个菜..."
    esac
    echo you choose is $menu
    echo you input is $REPLY
done

ღ ღ ღ 如果觉得文章对您有用,不妨赞一下ღ ღ ღ

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值