• 六、使用结构化命令


    使用if-then语句

    语法格式

    if command
    then
        commands
    fi

    注意:if是根据命令退出码来判断(echo $?=0),如果是0,则表示为真,执行后面的命令

    举例

    [root@tzPC ~]# cat if-1.sh
    #!/bin/bash
    if ls /mnt
    then
            echo "It worked"
    fi

     if-then-else语句

    语法格式

    if command ; then
        commands
    else
        commands
    fi

     举例

    [root@tzPC if]# cat if_2.sh 
    #!/bin/bash
    testuser=tz
    if grep $testuser /etc/passwd >/dev/null
    then
            echo "The bash files for user $testuser are:"
            ls -a /home/$testuser/.b*
            echo
    else
            echo "The user $testuser does not exist on this system."
            echo
    fi

    嵌套if

    语法结构

    if command1;then
        commands
    elif command2;then
        commands
    elif command3;then
        commands
    ...
    else 
        more commands
    fi

    举例

    查看tz用户是否存在

    [root@tzPC ~]# ls -d /home/tz
    /home/tz
    [root@tzPC ~]# echo $?
    0

     脚本

    [root@tzPC ~]# cat if-3.sh
    #!/bin/bash
    read -p "input a username:" name
    if grep $name /etc/passwd ;then
            echo "the user $name exists on this system!"
    elif ls -d /home/$name;then
            echo "the user $name not exists on this system!"
            echo "$name has a home directory"
    else
            echo "the user $name not exists on this system"
            echo "$name not has a direcotry"
    fi

    test命令

    test命令用于检查某个条件是否成立,如果成立就会退出并返回状态码0。不成立就会返回非0退出状态码。

    test命令可以判断三类条件

    • 数值比较
    • 字符串比较
    • 文件比较

    语法格式

    if test condition
    then 
        commands
    fi

    语法格式2

    注意方括号之间的空格

    if [ condition ]
    then
        commands
    fi

    如果不写condition会以非0的退出状态码退出

    [root@tzPC test]# bash test6.sh 
    No expression returns a False

    #脚本如下 [root@tzPC test]#
    cat test6.sh #!/bin/bash if test then echo "No expression returns a True" else echo "No expression returns a False" fi

     如果condition有内容,返回的退出码就为0,如果没有则不为0

    [root@tzPC test]# bash test6.sh 
    No expression returns a True

    #脚本如下
    [root@tzPC test]#
    cat test6.sh #!/bin/bash my_variable="Full"
    #my_variable="" 则会返回非0
    if test $my_variable then echo "No expression returns a True" else echo "No expression returns a False" fi

    数值比较

    参数

    说明

    示例

    -eq

    等于则为真

    n1 -eq n2

    -ne

    不等于则为真

    n1 -ne n2

    -gt

    大于则为真

    n1 -gt n2

    -ge

    大于等于则为真

    n1 -ge n2

    -lt

    小于则为真

    n1 -lt n2

    -le

    小于等于则为真

    n1 -le n2

    举例

    [root@tzPC ~]# cat test-1.sh
    #!/bin/bash
    if test 2 -eq 1 ; then
            echo ok
    else
            echo err
    fi

     或者

    [root@tzPC ~]# cat test-2.sh
    #!/bin/bash
    if [ 2 -eq 2 ] ;then
            echo ok
    else
            echo err
    fi

     举例

    [root@tzPC test]# bash numeric_test.sh 
    The test value 10 is greater than 5
    The values are different
    #脚本如下
    [root@tzPC test]# cat numeric_test.sh 
    #!/bin/bash
    value1=10
    value2=11
    if [ $value1 -gt 5  ]
    then 
            echo "The test value $value1 is greater than 5"
    fi
    #
    if [ $value1 -eq $value2 ]
    then 
            echo "The values are equal"
    else 
            echo "The values are different"
    fi

    数值比大小

    [root@tzPC ~]# cat test2.sh
    #!/bin/bash
    read -p "input var1 var2:" var1 var2
    if [ $var1 -gt $var2 ] ;then
            echo "$var1 > $var2"
    elif [ $var1 -lt $var2 ] ;then
            echo "$var1 < $var2"
    else
            echo "$var1=$var2"
    fi

     注意,bash shell只能处理整数,在condition 中写浮点数比较会报错。

    字符串比较

    参数.

    说明

    str1 == str2 或者

    str1 = str2

    检查str1 是否跟 str2相同

    str1 != str2

    检查str1 是否跟 str2不同

    -z str1

    检查str1 长度是否为0

    -n str1

    检查str1长度是否非0

    str1 > str2

    检查str1是否比str2大

    str1 < str2

    检查str1是否比str2小

    举例

    [root@tzPC ~]# cat test3.sh
    #!/bin/bash
    read -p "input your name :" name
    if [ $name == "root" ] ;then
            echo "you are super administrator"
    else
            echo "you are a general user"
    fi

    字符串比较需要注意

    • 大于号和小于号必须转义,要不然SHELL会把它当成重定向符号
    • 大于和小于它们的顺序和sort排序是不一样的
    • 在test比较测试中,它使用的是ASCII顺序,大写字母是小于小写字母的;sort命令使用的是系统的本地化语言设置中定义的排序顺序,对于英语,本地化设置制定了在排序中小写字母会出现在大写字母前。

    举例

    [root@tzPC test]# bash test4.sh
    test > Test
    #在比较测试中大写字母是小于小写字母的
    [root@tzPC test]# sort testfile 
    test
    Test
    #在sort中大写字母是大于小写字母的,sort默认从小到大排序

    #脚本如下 [root@tzPC test]#
    cat test4.sh #!/bin/bash var1=test var2=Test if [ $var1 > $var2 ] ;then echo "$var1 > $var2" else echo "$var1 < $var2" fi

     -z跟-n判断未被定义的变量长度会被判为0

    文件比较

    参数

    .说明

     -e file

    检查文件或目录是否存在

    -r file

    检查文件存在且可读

    -w file

    检查文件存在且可写

    -x file

    检查文件存在且可执行

    -s file

    检查文件存在且至少有一个字符

    -d file

    检查文件存在且为目录

    -f file

    检查文件存在且为普通文件

    -c file

    检查文件存在且为字符型文件

    -b file

    检查文件存在且为块特殊文件

    file1 -nt fle2

    检查file1是否比file2新

    file1 -ot file2

    检查file1是否比file2旧

    检查目录是否存在

    -d会检查指定的目录是否存在于系统中

    [root@tzPC script]# bash test11.sh 
    The /home/tz directory exists
    /home/tz
    [root@tzPC script]#
    cat test11.sh #!/bin/bash jump_directory=/home/tz if [ -d $jump_directory ];then echo "The $jump_directory directory exists" cd $jump_directory pwd else echo "The $jump_directory direcotry does not exist" fi

     检查文件或目录是否存在

    #!/bin/bash
    if [ -e /etc/passwd ] ; then
            echo ok
    else
            echo err
    fi 

     举例

    [root@tzPC ~]# test -e /etc/aaa.txt && echo ok || echo err

     检查文件是否存在

    [root@tzPC script]# bash test13.sh 
    
    The item being checked: /root
    
    The item,/root,does exits.
    But is it a file?
    
    No,/root is not a file.
    #脚本如下
    [root@tzPC script]# cat test13.sh
    #!/bin/bash
    item_name=$HOME
    echo
    echo "The item being checked: $item_name"
    echo
    if [ -e $item_name ]; then
            echo "The item,$item_name,does exits."
            echo "But is it a file?"
            echo
            if [ -f $item_name ];then
                    ehco "Yes,$item_name is a file."
            else
                    echo "No,$item_name is not a file."
            fi
    else 
            echo "The item,$item_name,does not exist."
            echo "Nothing to update"
    fi

    检查所属关系

    -O可以测试你是否是文件的属主

    root@tzPC script]# bash test18.sh 
    You are the owner of the /etc/passwd file
    [root@tzPC script]# cat test18.sh
    #!/bin/bash
    if [ -O /etc/passwd ];then
            echo "You are the owner of the /etc/passwd file"
    else 
            echo "Sorry,you are not the owner of the /etc/passwd file"
    fi

    检查默认属主关系

    -G只会检查文件的默认组,是否为用户的默认组,并不会检查用户所属的所有组。

    检查文件日期

    对两个文件的创建日期进行比较

    -nt比较一个文件是否比另一个文件新

    -ot比较一个文件是否比另一个文件旧

    注意:使用前须先确认文件是否存在

    [root@tzPC script]# bash test20.sh
    The test18.sh file is newer than test11.sh
    the test11.sh file is older than the test18.sh
    [root@tzPC script]# ll
    总用量 16
    -rw-r--r--. 1 root root 199 8月  16 22:31 test11.sh
    -rw-r--r--. 1 root root 158 8月  16 23:13 test18.sh

    #脚本如下
    [root@tzPC script]# cat test20.sh #!/bin/bash if [ test11.sh -nt test18.sh ];then echo "The test11.sh file is newer than test18.sh" else echo "The test18.sh file is newer than test11.sh" fi if [ test11.sh -ot test18.sh ];then echo "the test11.sh file is older than the test18.sh" fi

    清空日志目录

    #!/bin/bash
    # clear /var/log/messages
    
    #确定当前是root用户
    if [ $USER != "root" ];then
        echo "你必须使用root用户才能执行脚本"
        exit 10    #直接退出,并返回10
    fi
    
    #判断文件是否存在
    if [ ! -f /var/log/messages ];then
        echo "文件不存在"
        exit 12
    fi
    
    #保留最近100行的日志内容
    tail -100 /var/log/messages > /var/log/mesg.tmp
    
    #日志清理
    >/var/log/messages
    #cat /dev/null > /var/log/messages
    
    mv /var/log/mesg.tmp /var/log/messages
    echo "Logs clean up"
    注:退出码 exit ,取值范围是0-255

     退出码可以使用$?得到

    复合条件测试

    判断第一种:两个条件都为真或有一个为真就执行

    注意&&在[]外

    if [ command1 ] && (||) [ command2 ]; then    
       commands
    elif [ command3 ] && (||) [ command4 ]; then
        commands
    else
        commands
    fi

     判断第二种

    注意-a在[]内

    if [ command1 -a (-o) command2 -a (-o) command3 ]; then
    elif [command3  -a (-o) command4 ]; then
    else
       commands
    fi

     判断第三种

    [[...]]支持*,<,>等符号且不需要转义

    if [[ command1 && (||) command2 ]]; then
      commands elif [[ command3 && (||) command4 ]]; then else commands fi

     使用双括号(())

    • 双括号可以在比较过程中使用高级数学表达式。
    • 双括号中可以赋值,且不用转义。
    符号 描述
    val++ 后增
    val-- 后减
    ++val 先增
    --val 先减
    ! 求反
    - 位求反
    ** 幂运算
    << 左位移
    >> 右位移
    & 位布尔和
    | 位布尔或
    && 逻辑和
    || 逻辑或

    注意括号左右要有空格。

    [root@tzPC script]# bash test23.sh 
    The square of 10 is 100
    [root@tzPC script]# cat test23.sh 
    #!/bin/bash
    val1=10
    if (( $val1 ** 2 > 90 ));then
            ((val2 =$val1 ** 2 ))
            echo "The square of $val1 is $val2"
    fi

     使用双方括号

    • 双方括号支持模式匹配
    • [[...]]支持*,<,>等符号且不需要转义

    举例

    [root@tzPC ~]# if [[ $USER == ro*  ]] ;then echo "hello,$USER" ;else echo "$USER is not root";  fi
    hello,root

     当只有一个[],r*表示字符串r*,而不是r通配符*

    [root@tzPC ~]# if [ $USER == ro*  ] ;then echo "hello,$USER" ;else echo "$USER is not root";  fi
    root is not root

    这时候需要这样写

    [root@tzPC ~]#  if [[ $USER == [a-z]oot ]] ; then echo "hello,$USER" ; else echo $USER not ; fi
    hello,root

    [[ 。。。 ]]和[ 。。。]的区别汇总:

    1、所有的字符与逻辑运算符直接用“空格”分开,不能连到一起。

    2、在[… ]表达式中,常见的<需要加转义符,大小比较

    3、进行逻辑运算符&& 、||比较时;如果用的[ ]符号,则用在外面,如[… ] && [… ] || [ …]如果在[…]里面进行逻辑与或的比较,则用-a、-o进行表示,如[ x = y –a x < z –o x > m ]

    4、[[… ]] 运算符只是[… ]运算符的扩充;能够支持>符号运算不需要转义符;它还是以字符串比较大小。里面支持逻辑运算符 ||  && , 不再使用-a 、-o

    5、[[…]] && 而不是 -a 表示逻辑“与”;用 || 而不是 -o表示逻辑“或”

    6、[[… ]]可以进行算术扩展,而[ ... ]不可以

    7、[[...]]能用正则,而[...]不行

    8、双括号((  ))用于数学表达式

    9、双方括号号[[  ]]用于高级字符串处理,比如“模糊匹配”

    shell常见通配符:

    字符

    含义

    实例

    *

    匹配 0 或多个字符

    a*b  a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。

    ?

    匹配任意一个字符

    a?b  a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。

    [list] 

    匹配 list 中的任意单一字符

    a[xyz]b   a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。

    [!list] 

    匹配 除list 中的任意单一字符

    a[!0-9]b  a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。

    [c1-c2]

    匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z]

    a[0-9]b  0与9之间必须也只能有一个字符 如a0b, a1b... a9b。

    {string1,string2,...}

    匹配 sring1 或 string2 (或更多)其一字符串

    a{abc,xyz,123}b    a与b之间只能是abc或xyz或123这三个字符串之一。

    举例

    [root@tzPC ~]# ls /etc/*.conf
    /etc/asound.conf  /etc/host.conf   /etc/libaudit.conf   /etc/man_db.conf    /etc/rsyslog.conf   /etc/sudo-ldap.conf
    /etc/dracut.conf  /etc/kdump.conf  /etc/libuser.conf    /etc/mke2fs.conf    /etc/sestatus.conf  /etc/sysctl.conf
    /etc/e2fsck.conf  /etc/krb5.conf   /etc/locale.conf     /etc/nsswitch.conf  /etc/sos.conf       /etc/vconsole.conf
    /etc/fuse.conf    /etc/ld.so.conf  /etc/logrotate.conf  /etc/resolv.conf    /etc/sudo.conf      /etc/yum.conf
    [root@tzPC ~]# ls /etc/???.conf
    /etc/sos.conf  /etc/yum.conf
    [root@tzPC ~]# touch /home/tz/a{1,2,3}.txt
    [root@tzPC ~]# ls /home/tz/
    a1.txt  a2.txt  a3.txt  root
    [root@tzPC ~]# ls /home/tz/a[123].txt
    /home/tz/a1.txt  /home/tz/a2.txt  /home/tz/a3.txt
    [root@tzPC ~]# ls /home/tz/a[1,2,3].txt
    /home/tz/a1.txt  /home/tz/a2.txt  /home/tz/a3.txt

    case命令

    case命令会将指定的变量与不同模式进行比较。

    根据变量的不同取值进行比较从而分别执行不同命令操作

    适用于多分支,是一个多选择语句

    case     变量或表达式     in
                  变量或表达式1)
                         命令序列1
                         ;;
                变量或表达式2)
                         命令序列2
                         ;;
                         ……
                         *)  
                         默认命令序列
     esac

    举例

    [root@tzPC script]# cat test26.sh
    #!/bin/bash
    case $USER in
    tz | root)
            echo "Welcome,$USER"
            echo "Please enjoy your visit"
            ;;
    testing)
            echo "Special testing account"
            ;;
    rich)
            echo "Do not forget to log off when you're done"
            ;;
    *)
            echo "Sorry,you are not allowed here"
            ;;
    esac

     举例2

    [root@tzPC ~]# cat case1.sh
    #!/bin/bash
    cat <<eof
    ***************
    *  1. backup  *
    *  2. copy    *
    *  3. quit    *
    ***************
    eof
    read -p "Input a choose:" OP
    case $OP in
            1|backup)
                    echo "BACKUP..."
            ;;
            2|copy)
                    echo "COPY..."
            ;;
            3|quit)
                    exit
            ;;
            *)
                    echo "error"
    esac

     exit 后边写返回值,默认是0,可以通过$?取得。

    例2:编写一个启动apache服务脚本

    安装httpd服务

    yum -y install httpd

     脚本

    [root@tzPC ~]# cat case2.sh
    #!/bin/bash
    case $1 in
            start)
                    systemctl $1 httpd
                    ps aux|grep httpd
            ;;
            stop)
                    systemctl $1 httpd
                    ps aux|grep httpd
            ;;
            status)
                    systemctl $1 httpd
                    ps aux|grep httpd
            ;;
            restart)
                    systemctl $1 httpd
                    ps aux|grep httpd
            ;;
            *)
                    echo "USAGE: $0 start|stop|restart"
    esac

     学习来自:《Linux命令行与Shell脚本大全 第3版》第12章

    今天的学习是为了以后的工作更加的轻松!
  • 相关阅读:
    poj 2516 Minimum Cost (最小费用流 )
    new start
    关于c语言中的声明和定义
    多态性与虚函数之对象切片
    C专家编程之typedef
    QGroupBox设置边框
    多态性与虚函数之继承中的virtual 晚捆绑
    使用Map
    遍历控件
    C专家编程之枚举
  • 原文地址:https://www.cnblogs.com/tz90/p/13322345.html
Copyright © 2020-2023  润新知