美文网首页
shell脚本编写 之 条件选择,条件判断,循环语句

shell脚本编写 之 条件选择,条件判断,循环语句

作者: ghbsunny | 来源:发表于2017-09-03 11:30 被阅读0次

    1 概述

    编写shell脚本,一般离不开条件选择,条件判断以及循环语句。掌握这三个语法,将大大提高脚本的编写效率,使得脚本编写更加灵活,完成X相对复杂的工作

    2 条件选择if语句

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

    if是根据判读条件的命令的退出状态来执行命令,if语句可嵌套

    单分支

    if 判断条件;then

    条件为真的分支代码

    fi

    双分支

    if 判断条件; then

    条件为真的分支代码

    else

    条件为假的分支代码

    fi

    多分支

    if 判断条件1; then

    条件为真的分支代码

    elif 判断条件2; then

    条件为真的分支代码

    elif 判断条件3; then

    条件为真的分支代码

    else

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

    fi

    例子

    比较数字大小结果真假判断

    read -p "Please input nu: " nu

    [[ $nu =~ ^[0-9]+$ ]] || { echo "Your input is not num";exit 8; }

    if [ "$nu" -gt 90 ];then

    echo "$nu is bigger than 90"

    elif [ "$nu" -lt 50 ];then

    echo "$nu is less than 50"

    else

    echo "Your input $nu is between range 50-90"

    fi

    执行命令结果真假判断

    read -p "please input ip: " ip

    if  ping -c 1 -W 1 $ip &>/dev/null; then

    echo "$ip is up"

    elif grep "$ip" /root/list &>/dev/null

    then

    echo  "host "$ip" is under maitenance"

    else  echo "$ip is unexpectedly down,please check"

    fi

    3 条件判断:case语句

    语法如下

    case 变量引用($var,注意有$符号引用)  in

    PAT1)

    分支1

    ;;

    PAT2)

    分支2

    ;;

    ......

    *)

    默认分支

    ;;

    esac

    这里的分支x可以是命令的组合,不是单纯的一条命令

    case支持glob风格的通配符:

    *: 任意长度任意字符

    ?: 任意单个字符

    []:指定范围内的任意单个字符

    a|b: a或b,当匹配到不同的字符,但是要执行相同的分支命令是,可以用这个命令简化判断

    例子

    #!/bin/bash

    read -p "Please input your choice: " choice

    final=`echo "$choice" |tr [[:upper:]] [[:lower:]]`

    case $final in

    y|yes)

    echo "You input "$choice",and your choice is yes"

    ;;

    n|no)

    echo "You input "$choice",and your choice is no";

    ;;

    y???es)

    echo "You input $choice,it has three character between yes"

    ;;

    [sunny])

    echo "You input $choice,it only has one character"

    ;;

    *)

    echo "Your choice is $choice,it is not the answer"

    ;;

    esac

    截图如下

    4 循环语句

    将某代码段重复运行多次,以下三个关键字for, while, until各自的语法构成不同的循环语句

    其中

    for默认将列表的值依次执行完成后退出

    while和until有进入条件和退出条件

    重复运行的次数有两类

    a.循环次数事先已知

    b.循环次数事先未知

    4.1 for 循环

    4.1.1 for 常规的列表循环

    语法如下:

    for 变量名 (如 var,不需要加$引用变量值) in 列表;do

    循环体(命令组合)

    done

    for循环执行机制:

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

    for循环 列表 生成方式:

    (1) 直接给出列表

    (2) 整数列表:

    (a) {start..end}

    (b) $(seq[start [step]] end)

    (3) 返回列表的命令:$(COMMAND) 可以表达为`COMMAND`,反向单引号引起来

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

    (5) 变量引用;$@, $*

    4.1.2 例子:

    4.1.2.1 直接给出列表型

    i=1

    for var in a b c d

    do

    echo "$i cycle the var is $var"

    let i++

    done

    4.1.2.2 整数列表:{start..end..step}型

    如果不指定步进值(step),那么默认是步进1

    i=1

    for var in {3..15..2}

    do

    echo "$i cycle the var is $var"

    let i++

    done

    4.1.2.3 整数列表:$(seq[start [step]] end) 型

    #如果是 seq end  从1开始递增到end,每次增加1

    #如果是 seq start end  从start开始递增到end,每次递增1

    #如果是 seq[start] [step] [end] 从start开始,每次递增step,直到end

    i=1

    for var in $(seq 3 2 9)

    do

    echo "$i cycle the var is $var"

    let i++

    done

    4.1.2.4 返回列表的命令 $(COMMAND)型

    for var in $(ls /root/)

    do

    echo  "$i file is "$var", type is `file /root/$var`"

    let i++

    done

    echo

    4.1.2.5 使用glob,如:*.sh或/root/* 型

    for var in /root/*

    do

    echo  "$i file is "$var", type is `file $var`"

    let i++

    done

    echo

    4.1.2.6 变量引用;$@, $*型

    for var in $@

    do

    echo  "$i cycle,and now para is $1,var is $var,\$@ is $@"

    let i++

    shift

    done

    echo

    4.1.3  for循环的特殊格式:

    语法如下

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

    do

    循环体

    done

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

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

    双小括号方法,即((…))格式,也可以用于算术运算

    双小括号方法也可以使bash Shell实现C语言风格的变量操作,如((I++))

    该for循环的执行过程如下

    进入循环的时候,先不判断真假,直接执行 控制变量初始化

    然后执行  条件判断表达式 ,会判断真假 ,条件为真,开始进入循环

    执行循环

    执行完循环后

    执行  控制变量的修正表达式

    然后条件判断表达式

    执行  控制变量的修正表达式

    然后条件判断表达式,

    。。。。。。。

    直到不满足条件判断表达式这个条件后退出循环

    逻辑图如下

    例子

    read -p "Please input your nu to cal 1+2+...+nu: " nu

    s=0

    for ((i=1;i<=$nu;i=i+1))

    do

    s=$(($s+$i))

    echo "it is the $i cycle."

    done

    echo "1+2...+$nu=$s"

    以上脚本通过调试 bash -x 结果截图如下

    4.2 while循环

    4.2.1 语法

    while CONDITION(条件判断); do

    循环体

    done

    CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;

    条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环

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

    进入条件:CONDITION为true

    退出条件:CONDITION为false

    4.2.2 while循环的特殊用法:

    4.2.2.1 读入文件

    while read line; do  //注意,这里的line只是变量,可以自己命名

    循环体

    done < /PATH/FROM/SOMEFILE

    依次读取/PATH/FROM/SOMEFILE这个文件中的每一行,且将行赋值给变量line,每次读入一行进入循环,进行相应的处理

    4.2.2.2 将结果传入while

    将命令的结果传给while,用管道来传,每次读入命令结果得到一行

    命令 | while read 变量; do

    循环体

    其中管道命令只能处理标准输出,所以要确保命令有标准输出

    done

    4.2.2.3 创建无限循环

    while true; do

    循环体

    done

    4.2.3例子

    4.2.3.1 普通循环 九九乘法表

    i=1

    while [ "$i" -lt 10 ];do

    for (( j=1;j<="$i";j++)) do

    echo -e -n "$i*$j=$[ $i*$j ]\t"

    done

    echo

    let i++

    done

    4.2.3.2 读入文档内容

    while 每一次会把输入的文档/root/tt的每一行输入进行处理,等这行完成处理后,

    再输入文档的下一行,直到所有的循环都结束

    i=1

    while read line;do

    echo "$i cycle is \$line is <$line>"

    let i++

    echo "$line" | grep gt

    echo "$line" | sed -nr 's/useage=.*/for test sed/p'

    echo

    done

    4.2.3.3 管道输入

    以下命令将 df|grep /dev/sd 的结果通过管道一行一行传入给到变量line。然后进入循环做处理

    df|grep /dev/sd  | while read line;do

    dev=`echo "$line"| cut -d " " -f1`

    use=`echo "$line"| sed -r 's/.* ([0-9]+)%.*/\1/'`

    if [ "$use" -gt 3 ];then

    echo "Warning "$dev"'s usage is over 3%,it is $use,please check"

    else

    echo ""$dev"'s usage is safe,it is $use"

    fi

    done

    4.2.3.4 创建循环体

    每个两秒打印hello

    while true;do

    echo hello

    sleep 2

    done

    4.3 until

    4.3.1 语法

    until CONDITION; do

    循环体

    done

    进入条件:CONDITION 为false

    退出条件:CONDITION 为true

    until就是和while相反,一般可以用until实现的循环,都可以用while来实现,所以until可以了解一下即可。

    创建无限循环

    until false; do

    循环体

    Done

    4.3.2 例子

    4.3.2.1 until普通循环

    当i大于6的时候进入循环,小于或者等于6的时候退出循环

    i=10

    until [ $i -le 6 ];do

    echo \$i is $i,bigger than 6

    let i--

    echo "after i--,now i is $i"

    echo

    done

    4.3.2.2 无效循环的脚本

    打印it is false,然后睡2秒

    until false ;do

    echo "it is false"

    sleep 2

    done

    5 小结

    使用什么语法进行循环,或者是条件选择或者条件判断,都要根据具体情况来定,同时也是根据个人写脚本的习惯而定,比如有些人就喜欢用while来写循环语句,但是有一个原则就是,尽量把算法定好,防止多次的循环,占用大量的资源,对系统造成负担。

    相关文章

      网友评论

          本文标题:shell脚本编写 之 条件选择,条件判断,循环语句

          本文链接:https://www.haomeiwen.com/subject/xnrmdxtx.html