博主搬家至51CTO,初来乍到,请多指教。

此次我们来通过实例解析Linux shell脚本流程控制

Linux shell脚本流程控制可分为三类:顺序执行,条件选择执行,循环执行

顺序执行:简单理解就是逐行执行脚本内容,逐行解读,逐行执行。(此处不做实例解析)

条件选择执行:可以理解为先进行某一条件的判断选择,再决定执行怎样的脚本内容。常见语句if case

条件选择语句:if

if语句用法:

单分支

if 判断条件;then

条件为真的分支代码

fi

双分支

if 判断条件; then

条件为真的分支代码

else

条件为假的分支代码

fi

多分支

if 判断条件 1 ; then

条件为真的分支代码

elif 判断条件 2 ; then

条件为真的分支代码

elif 判断条件 3 ; then

条件为真的分支代码

else

以上条件都为假的分支代码

fi

注意:if语句支持嵌套,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if判断,否则的话向后进行判断。

经典实例解析:

根据输入的分数来判断ABCD等

#提示用户输入分数
read -p "please input your score : " score

#判断用户输入是否有误
[[ $score =~ ^[0-9]{1,2}$ ]] || { echo "your input wrong" ; exit; }

#if判断
if [ $score -gt 90 ]; then     #首先判断分数是否大于90
        echo "A"            #大于90的话执行
        elif [ $score -gt 70 ]; then   #不大于90,接着判断是否大于70
                echo "B"            #大于70小于90的话执行
        elif [ $score -gt 60 ]; then   #不大于70,接着判断是否大于60
                echo "C"            #大于60小于70的话执行
else                                 #判断条件都不满足:小于60的话执行
        echo "D"
fi

#变量删除
unset score

条件判断语句:case

case语句用法:

case 变量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...

*)

默认分支

;;

esac

注意:case的变量引用,用$引用某变量。

case 支持glob 风格的通配符:

*: 任意长度任意字符          ?: 任意单个字符

[] :指定范围内的任意单个字符   a|b: ab

经典实例解析:

根据输入的分数来判断ABCD等

read -p "please input your score : " score
[[ $score =~ ^[0-9]{1,2}$ ]] || { echo "your input wrong" ; exit; }
#case选择
case $score in              #case开头,引用变量 in
9?)                     #支持通配符:判断变量值为9X的话,执行该分支内容
        echo "A"
        ;;
7?|8?)                   #判断变量值为7X或8X的话,执行该分支内容,也可写为[78]?)
        echo "B"
        ;;
6?)                     #判断变量值为6X的话,执行该分支内容
        echo "C"
        ;;
*)                     #如果变量值不符合上述所有的判断,执行该分支内容
        echo "D"
        ;;
esac                    #以case的反序esac结束

unset score

循环执行:根据条件循环执行X次某一部分脚本内容(循环体)。常见循环语句for while until

循环语句:for(有两种用法)

for语句用法:

  • for 变量名 in 列表;do

    循环体

done

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

列表生成方式:

(1) 直接给出列表

(2) 整数列表:(a) {start..end}或者(b) $(seq[start [step]] end)

(3) 返回列表的命令$(COMMAND)或者``

(4) 使用glob,如:*.sh

(5) 变量引用,如:$@$*

  • for (( 控制变量初始化; 条件判断表达式; 控制变量的修正表达式))

do

循环体

done

解释:常用于数字循环。实现类似于C语言风格的操作

控制变量初始化:仅在运行到循环代码段时执行一次

控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

经典实例解析:

计算1到输入数字的所有值(1+2+...+X)的总和

#for语句用法1
read -p "请输入一个数字: " int

if `echo $int | grep "^[0-9]\+\b" &> /dev/null` ; then #判断用户输入是否为数字
        sum=0
        for i in $(seq $int) ; do         #将seq $int的执行结果作为列表循环可以写为`seq $int`
                let sum+=$i           #执行循环体内容,列表未结束的话,接着循环。
        done                       #do与done配套使用do开始,done结束循环。
        echo "总和为:$sum"
else
        echo "不要调皮,请输入数字"
fi
#for语句用法2
read -p "请输入一个数字: " int

if `echo $int | grep "^[0-9]\+\b" &> /dev/null` ; then
        for ((i=0,sum=0;i<=$int;i++)) ;do        #定义初始值,判断表达式,变量的修正
                let sum+=$i
        done
        echo $sum
else
        echo "不要调皮,请输入数字"
fi

循环语句:while

while语句的用法:

while CONDITION; do

    循环体

done

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

因此:CONDTION 一般应该有循环控制变量;而此变量的值会在循环体不断地被修正。

进入条件:CONDITION true

退出条件:CONDITION false

经典实例解析:

计算1到输入数字的所有值(1+2+...+X)的总和

read -p "请输入一个数字: " int
if `echo $int | grep "^[0-9]\+\b" &> /dev/null` ; then
        sum=0
        while [ 0 -lt $int ] ; do      #判断为真时,循环循环体,为假时退出循环。
                let sum+=$int
                let int--
        done
        echo "$sum"
else
        echo "不要调皮,请输入数字"
fi

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

while read line; do

    循环体

done < /PATH/FROM/SOMEFILE

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

经典实例解析:

计算1到输入数字的所有值(1+2+...+X)的总和

>line.txt      #清空文件
read -p "请输入一个数字: " int
if `echo $int | grep "^[0-9]\+\b" &> /dev/null` ; then
        seq $int > /shell/line.txt    #将数字每个数字一行导入文件
        sum=0
        while read line ;do           #读取每一行即数字,赋值给变量
                let sum+=$line
        done < /shell/line.txt
        echo "$sum"
else
        echo "不要调皮,请输入数字"
fi

循环语句:until

until循环用法与while循环一样,只是循环判断相反,while循环,当条件为真时执行循环体,为假时退出,而until循环,当条件为假时执行循环体,条件为真时退出。

经典实例解析:

计算1到输入数字的所有值(1+2+...+X)的总和

#将while示例中的while [ 0 -lt $int ] ; do  改为until [ 0 -gt $int ] ; do  注意两者的区别以及转换

循环控制语句:作用于循环体,用来控制满足某一条件的循环执行。常见控制语句:continue break shift

continue语句continue [n]跳过满足条件的某一层执行操作,继续进行下一次判断,最内层循环为第1层。依次类推。

经典实例解析:

计算1到100的值的总和(编)

for ((i=0,sum=0;i<=100;i++)) ; do
        [ $i -eq 50 ] && continue  #当变量i为50时,跳过计算50,执行下一个计算
        let sum+=$i
done
echo "$sum"
#最后输出结果为5000


break语句break [n]满足某一条件直接结束某一层循环,不进行下一次的判断,最内层循环为第1层,依次类推。

经典实例解析:

计算1到100的值的总和(编)

# 将continue示例中的continue改为break,即当变量i为50时,结束后续循环的执行
#最后输出结果为1225

shift语句:shift [n]常用于将位置参量列表左移指定次数,默认为左移一次,最左端的参数将被删除

经典实例解析:

[ $# -eq 0 ] && echo "please input args...."  #判断脚本后面是否接参数
while [ $# -ne 0 ] ; do
        echo "$@"
        shift         #左移一个参数,该参数将被删除
done
脚本运行结果:
[root@localhost shell]#shift.sh 1 2 3 4
1 2 3 4
2 3 4
3 4
4