• shell选择结构(if)



    一、条件判断

    1. 语法格式

    • 格式1:test条件表达式
    • 格式2:[ 条件表达式 ]
    • 格式3:[[ 条件表达式 ]](支持在正则表达式)
      test的参数很多,可以用man命令查看

    2. 条件判断相关参数

    1)判断文件存在与否

    -e	是否存在   不管是文件还是目录,只要存在,条件就成立
    -f	是否为普通文件
    -d	是否为目录
    -S	socket
    -p	pipe
    -c	character
    -b	block
    -L	软link
    
    三种语法格式:
     test -e file1	只要文件存在条件为真
     [ -d ~/tmp/files ]	判断目录是否存在,存在条件为真
     [ ! -d ~/tmp/files ]	判断目录是否存在,不存在条件为真
     [[ -f ~/tmp/file1 ]]	判断文件是否存在,并且是一个普通的文件
    
    -s 判断文件是否有内容(大小),非空文件条件满足
    说明:-s表示非空,! -s 表示空文件
    说明:file1中是有内容的
    
    [root@lamp tmp]# test -s file1
    [root@lamp tmp]# echo $?
    0
    [root@lamp tmp]# touch temp
    [root@lamp tmp]# cat temp
    [root@lamp tmp]# test -s temp;echo $?
    1
    [root@lamp tmp]# test ! -s temp;echo $?
    0
    [root@lamp tmp]# echo $?
    0
    [root@lamp tmp]# test ! -s file1;echo $?
    1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2)文件权限相关的判断

    -r	当前用户对其是否可读
    -w	当前用户对其是否可写
    -x	当前用户对其是否可执行
    -u	是否有suid
    -g	是否sgid
    -k	是否有t位
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3)两个文件的比较判断

    file1 -nt  file2	比较file1是否比file2新	
    file1 -ot  file2 	比较file1是否比file2旧
    file1 -ef  file2	比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
    
    test file1 -nt file2	
    [ file1 -ot file2 ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    [root@lamp tmp]# ll
    total 4
    -rw-r--r-- 1 root root 12 Aug  3 19:10 file1
    -rw-r--r-- 1 root root  0 Aug  3 19:17 file2
    drwxr-xr-x 2 root root  6 Aug  3 18:51 files
    -rw-r--r-- 1 root root  0 Aug  3 19:13 temp
    [root@lamp tmp]# test file1 -nt file2;echo $? # 比较file1是否比file2新
    1
    [root@lamp tmp]# test file1 -ot file2;echo $? # 比较file1是否比file2旧
    0
    [root@lamp tmp]# [ file1 -ef feil2 ];echo $? # 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
    1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4)整数之间的判断

    -eq	相等
    -ne	不等
    -gt	大于
    -lt	小于
    -ge   大于等于
    -le	小于等于
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5)字符串之间的判断

    -z  是否为空字符串   		字符串长度为0,就成立
    -n  是否为非空字符串    	只要字符串非空,就是成立
    string1 = string2 		是否相等
    string1 != string2 		不等
    
    [root@lamp tmp]# str1=abc
    [root@lamp tmp]# str2=qwer
    [root@lamp tmp]# test -z $str1
    [root@lamp tmp]# echo $?
    1
    [root@lamp tmp]# test -n $str1
    [root@lamp tmp]# echo $?
    0
    [root@lamp tmp]# [ $str1 = $str2 ]
    [root@lamp tmp]# echo $?
    1
    [root@lamp tmp]# [ $str1 != $str2 ];echo $?
    0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6)多重条件判断

    逻辑判断符号:

    • -a&& (and 逻辑与) 两个条件同时满足,整个大条件为真
    • -o|| (or 逻辑或) 两个条件满足任意一个,整个大条件为真
    [ 1 -eq 1 -a 1 -ne 0 ]				整个表达式为真
    [ 1 -eq 1 ] && [ 1 -ne 0 ]			
    
    
    [ 1 -eq 1 -o 1 -ne 1 ]				整个表达式为真
    [ 1 -eq 1 ] || [ 1 -ne 1 ]
    
    
    [root@lamp tmp]# [ 1 -eq 0 ] && echo true || echo false
    false
    [root@lamp tmp]# [ 1 -eq 1 ] && echo true || echo false
    true
    
    &&:前面的表达式为真
    ||:前面的表达式为假
    
    
    
    总结:
    1、; && ||都可以用来分割命令或者表达式
    2、; 完全不考虑前面的语句是否正确执行,都会执行;号后面的内容
    3、&& 需要考虑&&前面的语句的正确性,前面语句正确执行才会执行&&后的内容;反之亦然
    make && make install
    4、|| 需要考虑||前面的语句的非正确性,前面语句执行错误才会执行||后的内容;反之亦然
    5、如果&&和||一起出现,从左往右依次看,按照以上原则
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    一、流程控制语句

    1. 基本语法结构

    if

    if [ 条件 ];then
    		要执行的命令1
    		要执行的命令...
    fi
    
    • 1
    • 2
    • 3
    • 4

    if+else

    if [ 条件 ];then
    		要执行的命令
    	else
    		要执行的命令
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5

    if+elif+else

    if [ 条件1 ];then
    		要执行的命令1
    	elif [ 条件2 ];then
    		要执行的命令2
    	else
    		要执行的命令3
    fi
    
    #如果条件1满足,执行命令1后结束;
    #如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;
    #如果条件1和条件2都不满足执行命令3结束.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    嵌套if+else

    if [ 条件1 ];then
    		要执行的命令
    		if [ 条件2 ];then
    			要执行的命令
    		fi
    		else
    			if [ 条件3 ];then
    				要执行的命令
    			elif [ 条件4 ];then
    				要执行的命令
    			else
    				要执行的命令
    			fi
    fi
    
    #如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
    #如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;
    #如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 示例

    # 通过uid判断是否是root账号
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
    the user is admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
    the user is not admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
    the user is admin
    
    
    
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
    the user is admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
    the user is not admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
    the user is admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
    the user is admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
    the user is not admin
    [root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
    the user is admin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1)类C风格的数值比较

    类似于C语言的比较方法
    注意:在(( ))中,=表示赋值;==表示判断

    [test@lamp tmp]$ ((1==2));echo $?
    1
    [test@lamp tmp]$ ((1<2));echo $?
    0
    [test@lamp tmp]$ ((1>=1));echo $?
    0
    [test@lamp tmp]$ ((`id -u`==0));echo $?
    1
    [test@lamp tmp]$ unset $a
    [test@lamp tmp]$ ((a=123));echo $a
    123
    [test@lamp tmp]$ unset a
    [test@lamp tmp]$ ((a==123));echo $?
    1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2)字符串比较

    注意:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断

    [root@lamp tmp]# str="hello world";tmp="world"
    [root@lamp tmp]# [ $str = $tmp ];echo $?
    -bash: [: too many arguments
    2
    [root@lamp tmp]# [ "$str" = "$tmp" ];echo $?
    1
    [root@lamp tmp]# [ "$str" != "$tmp" ];echo $?
    0
    [root@lamp tmp]# [ "$str" !== "$tmp" ];echo $?
    -bash: [: !==: binary operator expected
    2
    [root@lamp tmp]# [ "$str" == "$tmp" ];echo $?
    1
    [root@lamp tmp]# test "$str" != "$tmp";echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2. 使用案例

    1)判断当前主机是否和远程主机是否能ping通

    1. 使用哪个命令实现 ping -c
    2. 根据命令的执行结果状态来判断是否通 $?
    3. 根据逻辑和语法结构来编写脚本(条件判断或者流程控制)
    #!/bin/bash
    # Name:ping.sh
    # Path:/test_shell/
    
    #获取远程主机的IP地址(定义变量让用户自己输入)
    read -p "请输入你要ping的远程主机ip:" ip
    #使用ping命令来判断是否和远程主机互通
    ping -c1 $ip &>/dev/null
    if [ $? -eq 0 ];then
            echo "当前主机和远程主机$ip是互通的"
    else
            echo "当前主机和远程主机$ip是不通的"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    或者

    #!/bin/bash
    # Name:ping.sh
    # Path:/test_shell/
    
    #获取远程主机的IP地址(定义变量让用户自己输入)
    read -p "请输入你要ping的远程主机ip:" ip
    #使用ping命令来判断是否和远程主机互通
    ping -c1 $ip &>/dev/null
    [ $? -eq 0 ] && echo "当前主机和远程主机$1是互通的" || echo "当前主机和远程主机$1是不通的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    测试

    [root@lamp test_shell]# ./ping.sh
    请输入你要ping的远程主机ip:www.baidu.com
    当前主机和远程主机是互通的
    [root@lamp test_shell]# ./ping.sh
    请输入你要ping的远程主机ip:192.168.44.25
    当前主机和远程主机是不通的
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2)判断一个进程是否存在

    思路:
    1.查看进程的相关命令ps -ef
    2.根据命令的返回状态值来判断进程是否存在 $?
    3.根据逻辑用脚本语言实现

    #!/bin/bash
    # Name:process.sh
    # Path:/test_shell
    # Usage:/test_shell/process.sh
    # Describe:判断一个进程是否存在
    
    #定义变量
    read -p "请输入要判断的进程名:" process
    #通过命令查看进程是否存在
    pgrep $process &>/dev/null
    #通过命令执行的状态判断是否存在
    if [ $? -eq 0 ];then
            echo "进程$process存在"
    else
            echo "进程$process不存在"
    fi
    
    
    pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
    选项
    -o:仅显示找到的最小(起始)进程号;
    -n:仅显示找到的最大(结束)进程号;
    -l:显示进程名称;
    -P:指定父进程号;pgrep -p 4764  查看父进程下的子进程id
    -g:指定进程组;
    -t:指定开启进程的终端;
    -u:指定进程的有效用户ID。
    ```shell
    ## 或者
    [ $? -eq 0 ] && echo "进程$process存在" || echo "进程$process不存在"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    测试

    [root@lamp test_shell]# chmod +x process.sh
    [root@lamp test_shell]# ./process.sh
    请输入要判断的进程名:httpd
    进程httpd存在
    [root@lamp test_shell]# ./process.sh
    请输入要判断的进程名:mysql
    进程mysql存在
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3)输入一个用户,用脚本判断该用户是否存在

    #!/bin/bash
    read -p "请输入需要判断的用户名:" user
    id $user &>/dev/null
    test $? -eq 0 && echo "$user用户存在" || echo "$user用户不存在"
    
    • 1
    • 2
    • 3
    • 4

    测试

    [root@lamp test_shell]# ./test_user.sh
    请输入需要判断的用户名:test
    test用户存在
    [root@lamp test_shell]# ls /home
    test
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4)判断vsftpd软件包是否安装,如果没有则自动安装(yum源已配好)

    #!/bin/bash
    rpm -q vsftpd &>/dev/null
    if [ $? -eq 0 ];then
            echo "vsftpd已经安装"
    else
            echo "该软件没有安装,正在安装..."
            yum install -y vsftpd &> /dev/null
    
            if [ $? -eq 0 ];then
                    echo "vsftpd安装成功"
            else
                    echo "vsftpd安装失败"
            fi
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试

    [root@lamp test_shell]# ./auto_yum.sh
    该软件没有安装,正在安装...
    vsftpd安装成功
    
    
    • 1
    • 2
    • 3
    • 4

    5)判断http服务是否已启动,如果已启动输出以下信息:

    httpd服务器已启动…
    httpd监听的端口是:
    httpd的进程PID是:

    #!/bin/bash
    systemctl status httpd &>/dev/null
    if [ $? -eq 0 ];then
                    port=`ss -naltp | grep httpd | cut -d : -f4`
                    pid=`ss -naltp | grep httpd | cut -d , -f2`
                    echo "httpd服务已经启动..."
                    echo "httpd监听的端口是" $port
                    echo "httpd的进程" $pid
            else
                    echo "htppd服务未启动"
    fi
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    测试

    [root@lamp test]# ./test_httpstop.sh
    httpd服务已经启动...
    httpd监听的端口是 80
    httpd的进程 pid=7518
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    Linux中的添加一块新的硬盘
    【算法】【递归与动态规划模块】字符串之间转换的最小代价
    文件分割与合并
    erlang练习题(二)
    计算机毕设(附源码)JAVA-SSM基于技术的高校学生勤工俭学管理系统的设计与开发
    FindMy技术智能防丢物品
    学习笔记
    Kafka 3.x.x 入门到精通(03)——对标尚硅谷Kafka教程
    java中如何让1+1=3
    事务的特性-原子性(Atomicity)、一致性(Consistency)、隔离性(Asolation)、持久性(Durability)
  • 原文地址:https://blog.csdn.net/weixin_53946852/article/details/126142122