• SHELL 中条件语句的运用 if for 条件测试语句


    if条件测试语句可以让脚本根据实际情况自动执行相应的命令。从技术角度来讲,if语句分为单分支结构、双分支结构、多分支结构;其复杂度随着灵活度一起逐级上升。

    if条件语句的单分支结构由if、then、fi关键词组成,而且只在条件成立后才执行预设的命令,相当于口语的“如果……那么……”。单分支的if语句属于最简单的一种条件判断结构,语法格式如图4-17所示。
    第4章 Vim编辑器与Shell命令脚本。第4章 Vim编辑器与Shell命令脚本。

    图4-17  单分支的if语句

    下面使用单分支的if条件语句来判断/media/cdrom文件是否存在,若存在就结束条件判断和整个Shell脚本,反之则去创建这个目录:

    [root@linuxprobe ~]# vim mkcdrom.sh
    #!/bin/bash
    DIR="/media/cdrom"
    if [ ! -e $DIR ]
    then
    mkdir -p $DIR
    fi
    

    由于第5章才讲解用户身份与权限,因此这里继续用“bash 脚本名称”的方式来执行脚本。在正常情况下,顺利执行完脚本文件后没有任何输出信息,但是可以使用ls命令验证/media/cdrom目录是否已经成功创建:

    [root@linuxprobe ~]# bash mkcdrom.sh
    [root@linuxprobe ~]# ls -d /media/cdrom
    /media/cdrom

    if条件语句的双分支结构由if、then、else、fi关键词组成,它进行一次条件匹配判断,如果与条件匹配,则去执行相应的预设命令;反之则去执行不匹配时的预设命令,相当于口语的“如果……那么……或者……那么……”。if条件语句的双分支结构也是一种很简单的判断结构,语法格式如图4-18所示。

    第4章 Vim编辑器与Shell命令脚本。第4章 Vim编辑器与Shell命令脚本。

    图4-18 双分支的if条件语句

    下面使用双分支的if条件语句来验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线信息,要么显示主机不在线信息。这里的脚本主要使用ping命令来测试与对方主机的网络联通性,而Linux系统中的ping命令不像Windows一样尝试4次就结束,因此为了避免用户等待时间过长,需要通过-c参数来规定尝试的次数,并使用-i参数定义每个数据包的发送间隔,以及使用-W参数定义等待超时时间。

    [root@linuxprobe ~]# vim chkhost.sh
    #!/bin/bash
    ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
    if [ $? -eq 0 ]
    then
    echo "Host $1 is On-line."
    else
    echo "Host $1 is Off-line."
    fi
    

    我们在4.2.3小节中用过$?变量,作用是显示上一次命令的执行返回值。若前面的那条语句成功执行,则$?变量会显示数字0,反之则显示一个非零的数字(可能为1,也可能为2,取决于系统版本)。因此可以使用整数比较运算符来判断$?变量是否为0,从而获知那条语句的最终判断情况。这里的服务器IP地址为192.168.10.10,我们来验证一下脚本的效果:

    [root@linuxprobe ~]# bash chkhost.sh 192.168.10.10
    Host 192.168.10.10 is On-line.
    [root@linuxprobe ~]# bash chkhost.sh 192.168.10.20
    Host 192.168.10.20 is Off-line.
    

    if条件语句的多分支结构由if、then、else、elif、fi关键词组成,它进行多次条件匹配判断,这多次判断中的任何一项在匹配成功后都会执行相应的预设命令,相当于口语的“如果……那么……如果……那么……”。if条件语句的多分支结构是工作中最常使用的一种条件判断结构,尽管相对复杂但是更加灵活,语法格式如图4-19所示。 第4章 Vim编辑器与Shell命令脚本。第4章 Vim编辑器与Shell命令脚本。

    图 4-19 多分支的if条件语句

    下面使用多分支的if条件语句来判断用户输入的分数在哪个成绩区间内,然后输出如Excellent、Pass、Fail等提示信息。在Linux系统中,read是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p参数用于向用户显示一定的提示信息。在下面的脚本示例中,只有当用户输入的分数大于等于85分且小于等于100分,才输出Excellent字样;若分数不满足该条件(即匹配不成功),则继续判断分数是否大于等于70分且小于等于84分,如果是,则输出Pass字样;若两次都落空(即两次的匹配操作都失败了),则输出Fail字样:

    [root@linuxprobe ~]# vim chkscore.sh
    #!/bin/bash
    read -p "Enter your score(0-100):" GRADE
    if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
    echo "$GRADE is Excellent"
    elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
    echo "$GRADE is Pass"
    else
    echo "$GRADE is Fail" 
    fi
    [root@linuxprobe ~]# bash chkscore.sh
    Enter your score(0-100):88
    88 is Excellent
    [root@linuxprobe ~]# bash chkscore.sh 
    Enter your score(0-100):80
    80 is Pass
    

    下面执行该脚本。当用户输入的分数分别为30和200时,其结果如下:

    [root@linuxprobe ~]# bash chkscore.sh  
    Enter your score(0-100):30
    30 is Fail
    [root@linuxprobe ~]# bash chkscore.sh
    Enter your score(0-100):200 
    200 is Fail

    为什么输入的分数为200时,依然显示Fail呢?原因很简单—没有成功匹配脚本中的两个条件判断语句,因此自动执行了最终的兜底策略。可见,这个脚本还不是很完美,建议读者自行完善这个脚本,使得用户在输入大于100或小于0的分数时,给予Error报错字样的提示。

    如果在 if中 还 想 加 入 更多的 条件 ,就 只 需要 添加    

    elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
    echo "$GRADE is Pass"

    #!/bin/bash
    read -p "Enter your score(0-100):" GRADE
    if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
    echo "$GRADE is Excellent"
    elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
    echo "$GRADE is henhao"
    elif [ $GRADE -ge 60 ] && [ $GRADE -le 69 ] ; then
    echo "$GRADE is Pass"
    else
    echo "$GRADE is Fail"
    fi




    
    
    
    4.3.2 for条件循环语句

    for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用for循环语句再适合不过了。for循环语句的语法格式如图4-20所示。

    第4章 Vim编辑器与Shell命令脚本。第4章 Vim编辑器与Shell命令脚本。

    图4-20  for循环语句的语法格式

    下面使用for循环语句从列表文件中读取多个用户名,然后为其逐一创建用户账户并设置密码。首先创建用户名称的列表文件users.txt,每个用户名称单独一行。读者可以自行决定具体的用户名称和个数:

    [root@linuxprobe ~]# vim users.txt
    andy
    barry
    carl
    duke
    eric
    george
    

    接下来编写Shell脚本Example.sh。在脚本中使用read命令读取用户输入的密码值,然后赋值给PASSWD变量,并通过-p参数向用户显示一段提示信息,告诉用户正在输入的内容即将作为账户密码。在执行该脚本后,会自动使用从列表文件users.txt中获取到所有的用户名称,然后逐一使用“id 用户名”命令查看用户的信息,并使用$?判断这条命令是否执行成功,也就是判断该用户是否已经存在。

    需要多说一句,/dev/null是一个被称作Linux黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。

    [root@linuxprobe ~]# vim Example.sh
    #!/bin/bash
    read -p "Enter The Users Password : " PASSWD
    for UNAME in `cat users.txt`
    do
    id $UNAME &> /dev/null
    if [ $? -eq 0 ]
    then
    echo "Already exists"
    else
    useradd $UNAME &> /dev/null
    echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
    if [ $? -eq 0 ]
    then
    echo "$UNAME , Create success"
    else
    echo "$UNAME , Create failure"
    fi
    fi
    done
    

    执行批量创建用户的Shell脚本Example.sh,在输入为账户设定的密码后将由脚本自动检查并创建这些账户。由于已经将多余的信息通过输出重定向符转移到了/dev/null黑洞文件中,因此在正常情况下屏幕窗口除了“用户账户创建成功”(Create success)的提示后不会有其他内容。

  • 相关阅读:
    无聊,只发两张图……
    LA
    “万能数据库查询分析器”5.04 发布,撰写的相关技术文章达63篇
    HDU 1010Tempter of the Bone(奇偶剪枝回溯dfs)
    uva 10051 Tower of Cubes(DAG最长路)
    uva 103 Stacking Boxes(DAG)
    异步处理(列出所有文件)
    Android开发8:UI组件TextView,EditText,Button
    植物-蔬菜:红菜苔
    植物-蔬菜:菜苔
  • 原文地址:https://www.cnblogs.com/linuxandy/p/11075913.html
Copyright © 2020-2023  润新知