Shell脚本之条件选择与循环

来源:互联网 发布:淘宝到v3是否可以贷款 编辑:程序博客网 时间:2024/05/16 05:21

前言

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/bashread -p 'Can I ask you out to play?(yes|no)'  gocase    $go    in[yY]|[yY][eE][sS])        echo "Let's go."        ;;[nN]|[nN][oO])        echo "That's too bad"        ;;*)        echo "Are you turning me down?"        ;;esacunset 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    donedone

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

列表生成方式:

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

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

if [ $# = 0 ];then     read -p "你想打印几行的等腰三角形:" selse    s=$1fi    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 yangroutangdo    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 $REPLYdone

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

原创粉丝点击