03-条件判断

为什么学条件判断

  1. 自动化任务处理的需求

    • 在系统管理和运维工作中,经常需要批量处理任务。例如,你可能需要在服务器上检查一系列文件是否存在,如果存在就进行备份操作。通过Bash条件判断,可以编写脚本来自动完成这个过程。假设你有一个脚本,用于备份配置文件:
      if [ ! -d /backup ];then
                    echo "/backup备份目录不存在,帮您创建了!"
                    mkdir -p /backup
      fi
      # 666
      for file in /etc/*.conf; do
        if [ -e $file ]; then
            cp $file /backup/$(basename $file)
        fi
      done
      
    • 这个脚本会遍历/etc/目录下所有以.conf结尾的文件。对于每个文件,它会使用条件判断-e来检查文件是否存在。如果文件存在,就将其复制到/backup/目录下。这种自动化的任务处理可以大大提高工作效率,减少人工操作的错误。
  2. 软件安装和配置的灵活性

    • 当编写软件安装脚本时,Bash条件判断可以根据系统环境做出不同的决策。例如,不同的Linux发行版可能将软件安装在不同的目录下,或者需要不同的依赖包。通过条件判断,可以使安装脚本适应多种环境。
    • 比如,以下是一个简单的软件安装脚本片段,用于判断系统是基于Debian(如Ubuntu)还是基于Red Hat(如CentOS)来安装软件:
      if [ -f /etc/debian_version ]; then
        apt -y install software_name
      elif [ -f /etc/redhat-release ]; then
        yum -y install software_name
      else
        echo "Unsport system.."
      fi
      
    • 这个脚本通过检查特定的系统版本文件(/etc/debian_version用于Debian系系统,/etc/redhat - release用于Red Hat系系统)来决定使用apt还是yum命令安装软件。如果无法识别系统类型,会给出相应的提示信息。
  3. 错误处理和健壮性增强

    • 在脚本执行过程中,可能会遇到各种错误情况,如文件不存在、权限不足等。使用Bash条件判断可以捕获这些错误并采取适当的措施。例如:
      file_path="/tmp/file.txt"
      if [ -e $file_path ]; then
        if [ -r $file_path ]; then
            cat $file_path
        else
            echo "You don't have permission to read this file"
        fi
      else
        echo "File does not exist"
      fi
      
    • 这个脚本首先检查文件是否存在(-e操作符),如果存在,再检查是否有读取权限(-r操作符)。如果有读取权限,就显示文件内容;如果没有读取权限,会给出相应提示;如果文件不存在,也会给出提示。这样可以让脚本在遇到不同问题时能够合理地处理,增强了脚本的健壮性。
  4. 实现复杂的逻辑和流程控制

    • 对于复杂的系统管理任务或数据处理任务,需要根据多种条件来控制程序的流程。Bash条件判断可以帮助实现类似于其他高级编程语言中的复杂逻辑。例如,在一个日志分析脚本中,可能需要根据日志的级别和内容来采取不同的操作:
      log_file="/var/log/syslog"
      while read line; do
        if echo $line | grep -q "ERROR"; then
            echo "Error found: $line" >> errors.log
        elif echo $line | grep -q "WARN"; then
            echo "Warning found: $line" >> warnings.log
        else
            continue
        fi
      done < $log_file
      
    • 这个脚本逐行读取日志文件(access.log)。如果某行包含“ERROR”字样,就将该行内容通过邮件发送给管理员;如果包含“WARN”字样,就将该行内容追加到warnings.log文件中;否则,跳过该行继续读取下一行。这种复杂的流程控制使得脚本能够根据不同的条件进行智能的处理。

我们目前写的shell脚本都是按照顺序,自上而下的,依次读取命令,且执行。

但是如果你要控制程序的执行顺序,修改这个顺序,那就得对脚本进行逻辑控制。

那么就必须得进行条件判断了。

坑记录。

1.务必注意,语法,中括号,条件测试符号左右两边的空格,别漏了。

2.条件判断里,关于变量是否添加双引号、本质上不一样的。。。。

image-20220616142651255

0.学前预览

先看下,系统自带的脚本,shell的语法,在你学习了之后,就看得懂了,也可以模仿着写。

image-20220616221657001

#!/bin/sh
printf "Are you sure you want to uninstall Webmin? (y/n) : "
read answer
printf "\n"
if [ "$answer" = "y" ]; then
        echo "Removing Webmin package .."
        rm -f /usr/share/webmin/authentic-theme/manifest-*
        dpkg --remove --force-depends webmin
        systemctlcmd=`which systemctl 2>/dev/null`
        if [ -x "$systemctlcmd" ]; then
                $systemctlcmd stop webmin >/dev/null 2>&1 </dev/null
                rm -f /lib/systemd/system/webmin.service
                $systemctlcmd daemon-reload
        fi
        echo ".. done"
fi
https://github.com/guohongze/adminset/blob/master/install/server/auto_install.sh

1.基于文件进行条件判断

我们这里先来学习这个条件判断的语法,下一步才进入if语句的学习。

常用参数

条件判断内容 操作符 示例 说明
文件是否存在 -e if [ -e file.txt ]; then echo "文件存在"; fi 如果file.txt存在,条件为真,执行echo命令
是否为普通文件 -f if [ -f normal_file ]; then echo "是普通文件"; fi 如果normal_file是普通文件(非目录、设备文件等),条件为真
是否为目录 -d if [ -d dir ]; then echo "是目录"; fi 如果dir是目录,条件为真
是否为符号链接 -L if [ -L link ]; then echo "是符号链接"; fi 如果link是符号链接,条件为真
是否可读 -r if [ -r file_path ]; then echo "可读"; fi 对于file_path指定的文件,如果有可读权限,条件为真
是否可写 -w if [ -w file_path ]; then echo "可写"; fi 如果file_path有可写权限,条件为真
是否可执行 -x if [ -x file_path ]; then echo "可执行"; fi 如果file_path有可执行权限,条件为真
文件1是否比文件2新 -nt if [ file1 -nt file2 ]; then echo "文件1比文件2新"; fi 比较两个文件的新旧,文件1新则条件为真
文件1是否比文件2旧 -ot if [ file1 -ot file2 ]; then echo "文件1比文件2旧"; fi 比较两个文件的新旧,文件1旧则条件为真

更多参数

做好笔记即可,看来回来查查

test 命令最短的定义可能是评估一个表达式;如果条件为真,则返回一个 0 值。如果表达式不为真,则返回一个大于 0 的值 — 也可以将其称为假值。检查最后所执行命令的状态的最简便方法是使用 $? 值。

参数:

1. 关于某个文件名的『类型』侦测(存在与否),如 test -e filename 

-e 该『文件名』是否存在?(常用) 
-f 该『文件名』是否为文件(file)?(常用) 
-d 该『文件名』是否为目录(directory)?(常用) 
-b 该『文件名』是否为一个 block device 装置? 
-c 该『文件名』是否为一个 character device 装置? 
-S 该『文件名』是否为一个 Socket 文件? 
-p 该『文件名』是否为一个 FIFO (pipe) 文件? 
-L 该『文件名』是否为一个连结档? 

2. 关于文件的权限侦测,如 test -r filename 

-r 侦测该文件名是否具有『可读』的属性? 
-w 侦测该文件名是否具有『可写』的属性? 
-x 侦测该文件名是否具有『可执行』的属性? 
-u 侦测该文件名是否具有『SUID』的属性? 
-g 侦测该文件名是否具有『SGID』的属性? 
-k 侦测该文件名是否具有『Sticky bit』的属性? 
-s 侦测该文件名是否为『非空白文件』? 

3. 两个文件之间的比较,如: test file1 -nt file2 

-nt (newer than)判断 file1 是否比 file2 新 
-ot (older than)判断 file1 是否比 file2 旧 
-ef 判断 file2 与 file2 是否为同一文件,可用在判断 hard link 的判定上。 主要意义在判定,两个文件是否均指向同一个 inode 哩! 

4. 关于两个整数之间的判定,例如 test n1 -eq n2 

-eq 两数值相等 (equal) 
-ne 两数值不等 (not equal) 
-gt n1 大于 n2 (greater than) 
-lt n1 小于 n2 (less than) 
-ge n1 大于等于 n2 (greater than or equal) 
-le n1 小于等于 n2 (less than or equal) 

5. 判定字符串的数据 

test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true 
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。
注: -n 亦可省略 
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true 
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false 

6. 多重条件判定,例如: test -r filename -a -x filename 

-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。 
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。 
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true

结合test命令

  1. test命令的基本介绍

    • test命令是一个在Bash中进行条件测试的内置命令,它和使用[ ]进行条件测试的功能基本相同,只是语法略有不同。实际上,在使用[ ]时,Bash会将其解释为test命令,例如[ -e file.txt ]等价于test -e file.txt
  2. 使用test进行文件测试

    • 文件存在测试
      if test -e file.txt; then
        echo "文件存在。"
      else
        echo "文件不存在。"
      fi
      
    • 这个例子使用test -e file.txt来检查file.txt是否存在。如果存在,将打印“文件存在。”,否则打印“文件不存在。”。
    • 文件类型测试
      if test -f normal_file; then
        echo "这是一个普通文件。"
      else
        echo "这不是一个普通文件。"
      fi
      
    • 这里使用test -f来检查normal_file是否是普通文件。同样,你可以使用test -d来检查是否是目录,test -L来检查是否是符号链接等。
    • 文件权限测试
      if test -r file_path; then
        echo "文件具有可读权限。"
      else
        echo "文件没有可读权限。"
      fi
      
    • 上述代码使用test -r来检查file_path是否具有可读权限。类似地,可以使用test -w检查可写权限,test -x检查可执行权限。
  3. 使用test进行字符串测试

    • 字符串相等测试
      str1="hello"
      str2="hello"
      if test "$str1" = "$str2"; then
        echo "两个字符串相等。"
      else
        echo "两个字符串不相等。"
      fi
      
    • 这里使用test "$str1" = "$str2"来判断两个字符串是否相等,确保使用双引号将变量括起来,以避免空变量带来的问题。
    • 字符串长度测试(间接方法)
      str="abcdefg"
      if test ${#str} -gt 5; then
        echo "字符串长度大于 5。"
      else
        echo "字符串长度小于或等于 5。"
      fi
      
    • 通过${#str}获取字符串的长度,并使用test和数字比较操作符(如-gt)来判断字符串长度是否大于 5。
  4. 使用test进行数字测试

    • 数字相等测试
      num1=10
      num2=20
      if test $num1 -eq $num2; then
        echo "两个数字相等。"
      else
        echo "两个数字不相等。"
      fi
      
    • 这里使用test $num1 -eq $num2来检查两个数字是否相等。你可以使用-ne(不等于)、-lt(小于)、-gt(大于)、-le(小于等于)、-ge(大于等于)等操作符进行不同的数字比较。
  5. test命令的逻辑操作符

    • 逻辑与:使用-a进行逻辑与操作。例如,要检查文件是否既存在又可读:
      if test -e file.txt -a -r file.txt; then
        echo "文件存在且可读。"
      else
        echo "文件不存在或不可读。"
      fi
      
    • 此代码使用test -e file.txt -a -r file.txt来判断文件是否存在且可读。只有当文件存在并且有可读权限时,条件才为真。
    • 逻辑或:使用-o进行逻辑或操作。例如,检查文件是否可写或可执行:
      if test -w file.txt -o -x file.txt; then
        echo "文件可写或可执行。"
      else
        echo "文件既不可写也不可执行。"
      fi
      
    • 上述代码使用test -w file.txt -o -x file.txt来判断文件是否可写或可执行。只要文件具有可写权限或可执行权限中的一个,条件就为真。
    • 逻辑非:使用!进行逻辑非操作。例如,检查文件是否不存在:
      if test! -e file.txt; then
        echo "文件不存在。"
      else
        echo "文件存在。"
      fi
      
    • 这里使用test! -e file.txt来判断文件是否不存在。如果文件不存在,条件为真,将打印“文件不存在。”。
  6. test命令的注意事项

    • 对于复杂的条件测试,使用test命令时,要注意操作符的顺序和逻辑的正确性。
    • 当使用多个条件时,需要根据实际需求合理运用逻辑操作符,避免逻辑混乱。
    • 在组合使用不同的条件测试时,最好使用括号和转义字符来确保条件的清晰和准确,例如:
      if test \( -e file1.txt -a \( -r file1.txt -o -w file1.txt \) \); then
        echo "文件存在,并且可读写。"
      else
        echo "文件不存在或不可读写。"
      fi
      
    • 在这个例子中,使用\(\)对条件进行分组,以确保逻辑的清晰,先判断文件是否存在,然后判断是否可读或可写。同时使用转义字符\来避免括号被错误解释。

test 条件语句

为真
[root@yuchaoit666 ~/p3-shell]#touch yuchaoit.log
[root@yuchaoit666 ~/p3-shell]#
[root@yuchaoit666 ~/p3-shell]#
[root@yuchaoit666 ~/p3-shell]#test -f "yuchaoit.log" && echo "true" || echo "false"
true


为假
[root@yuchaoit666 ~/p3-shell]#test -f "666yuchaoit.log" && echo "true" || echo "false"
false

写法2

[ 条件语句 ]

[root@yuchaoit666 ~/p3-shell]#[ -f "666yuchaoit.log" ] && echo "true" || echo "false"
false
[root@yuchaoit666 ~/p3-shell]#
[root@yuchaoit666 ~/p3-shell]#
[root@yuchaoit666 ~/p3-shell]#[ -f "yuchaoit.log" ] && echo "true" || echo "false"
true
[root@yuchaoit666 ~/p3-shell]#

测试常用条件参数

俩写法

1.判断ansible的主机清单文件是否存在,不存在提示用户先创建再使用ansible命令。

----------------------------------------------------------------------------------


# 普通文件
[ -f /etc/ansible/hosts ] && echo "主机清单hosts文件存在..."  || echo "先去创建主机清单hsots文件!!"

----------------------------------------------------------------------------------


# 文件存在
[ -e /etc/ansible/hosts ] && echo "主机清单hosts文件存在..."  || echo "先去创建主机清单hsots文件!!"

----------------------------------------------------------------------------------



# 注意坑,root怕你这权限吗?
[ -r /etc/ansible/hosts ] && echo "主机清单hosts允许读取!!"  || echo "无权读取!!"

[ -w /etc/ansible/hosts ] && echo "主机清单hosts允许写入!!"  || echo "无权写入!!"

[ -x /etc/ansible/hosts ] && echo "主机清单hosts允许执行!!"  || echo "无权执行!!"
----------------------------------------------------------------------------------



# 文件里有内容吗?
# 试试
>/etc/ansible/hosts
# 条件判断
[ -s /etc/ansible/hosts ] && echo "hosts清单文件有内容!!"  || echo "hosts文件为空,请写入!!"

----------------------------------------------------------------------------------



几个特殊文件,看看有内容吗
root@yuchaoit666 ~/p3-shell]#[ -s /dev/zero ] && echo true || echo false
false

[root@yuchaoit666 ~/p3-shell]#[ -s /dev/null ] && echo true || echo false
false

[root@yuchaoit666 ~/p3-shell]#[ -s /etc/passwd ] && echo true || echo false
true


----------------------------------------------------------------------------------
test命令写法
[root@yuchaoit666 ~/p3-shell]#test -s /etc/passwd  && echo true || echo false
true

[root@yuchaoit666 ~/p3-shell]#test -s /etc/passwddddd  && echo true || echo false
false

条件测试,综合案例

以下是一个使用bash进行条件测试的综合案例,包含了多种条件测试选项,如文件测试、字符串测试和数值测试。

#!/bin/bash

# 文件测试
if [ -e "testfile.txt" ]; then
    echo "文件 testfile.txt 存在。"
else
    echo "文件 testfile.txt 不存在。"
fi

# 目录测试
if [ -d "testdir" ]; then
    echo "目录 testdir 存在。"
else
    echo "目录 testdir 不存在。"
fi

# 字符串测试
str1="hello"
str2="world"
if [ "$str1" == "$str2" ]; then
    echo "字符串 str1 和 str2 相等。"
else
    echo "字符串 str1 和 str2 不相等。"
fi

if [ -z "$str1" ]; then
    echo "字符串 str1 长度为 0。"
else
    echo "字符串 str1 长度不为 0。"
fi

# 数值测试
num1=10
num2=20
if [ $num1 -eq $num2 ]; then
    echo "num1 等于 num2。"
elif [ $num1 -lt $num2 ]; then
    echo "num1 小于 num2。"
else
    echo "num1 大于 num2。"
fi

# 组合条件测试
if [ -e "testfile.txt" ] && [ -d "testdir" ]; then
    echo "文件 testfile.txt 存在且目录 testdir 存在。"
elif [ -e "testfile.txt" ] || [ -d "testdir" ]; then
    echo "文件 testfile.txt 存在或目录 testdir 存在。"
else
    echo "文件 testfile.txt 和目录 testdir 都不存在。"
fi

代码解释

  1. 文件测试

    • [ -e "testfile.txt" ]:检查文件 testfile.txt 是否存在。-e 选项用于测试文件是否存在。
    • [ -d "testdir" ]:检查目录 testdir 是否存在。-d 选项用于测试目录是否存在。
  2. 字符串测试

    • [ "$str1" = "$str2" ]:比较字符串 str1str2 是否相等。
    • [ -z "$str1" ]:检查字符串 str1 的长度是否为 0。-z 选项用于测试字符串长度是否为 0。
  3. 数值测试

    • [ $num1 -eq $num2 ]:检查 num1 是否等于 num2-eq 是数值相等的测试选项。
    • [ $num1 -lt $num2 ]:检查 num1 是否小于 num2-lt 是小于的测试选项。
  4. 组合条件测试

    • [ -e "testfile.txt" ] && [ -d "testdir" ]:使用 && 逻辑与运算符,当文件 testfile.txt 存在且目录 testdir 存在时执行相应代码。
    • [ -e "testfile.txt" ] || [ -d "testdir" ]:使用 || 逻辑或运算符,当文件 testfile.txt 存在或目录 testdir 存在时执行相应代码。

使用说明

  1. 将上述代码保存为一个文件,例如 test.sh
  2. 打开终端,使用 chmod +x test.sh 为文件添加执行权限。
  3. 运行脚本:./test.sh

这个案例涵盖了bash中常见的条件测试类型,包括文件、目录、字符串和数值的测试,以及逻辑运算符的使用,可以帮助你理解和掌握bash中的条件测试操作。

2.基于整数判断

比较操作 操作符 示例 说明
相等 -eq if test $num1 -eq $num2; then echo "相等"; fi $num1 等于 $num2 时,条件为真
不相等 -ne if test $num1 -ne $num2; then echo "不相等"; fi $num1 不等于 $num2 时,条件为真
小于 -lt if test $num1 -lt $num2; then echo "小于"; fi $num1 小于 $num2 时,条件为真
大于 -gt if test $num1 -gt $num2; then echo "大于"; fi $num1 大于 $num2 时,条件为真
小于等于 -le if test $num1 -le $num2; then echo "小于等于"; fi $num1 小于或等于 $num2 时,条件为真
大于等于 -ge if test $num1 -ge $num2; then echo "大于等于"; fi $num1 大于或等于 $num2 时,条件为真

在使用上述数值比较操作符时,以下是一些需要注意的点:

  • 确保比较的是数字,而不是字符串。例如,在使用 test[ ] 进行条件判断时,$num1$num2 应该是数字或可被解析为数字的变量。
  • 示例中的 test 命令也可以用 [ ] 代替,如 if [ $num1 -eq $num2 ]; then echo "相等"; fi
  • 对于复杂的逻辑判断,可以结合逻辑运算符,例如:
    num1=5
    num2=10
    num3=15
    if [ $num1 -lt $num2 -a $num2 -lt $num3 ]; then
        echo "num1 < num2 < num3"
    fi
    
    此代码使用 -a 逻辑与运算符来判断 num1 是否小于 num2 并且 num2 是否小于 num3

这些数值比较操作符在脚本编写中非常有用,例如:

# 检查系统负载是否过高
load=$(uptime | awk '{print $10}' | cut -d. -f1)
if [ $load -gt 5 ]; then
    echo "系统负载过高!"
else
    echo "系统负载正常。"
fi

在这个脚本中,使用 uptime 命令获取系统负载,通过 awkcut 处理输出,最后使用 -gt 操作符来判断系统负载是否超过 5,根据结果输出相应信息。

此外,还可以在循环和函数中使用数值判断,例如:

# 打印 1 到 10 的偶数
for ((i=1; i<=10; i++)); do
    if [ $((i % 2)) -eq 0 ]; then
        echo $i
    fi
done

此代码使用 for 循环从 1 到 10 遍历数字,通过 $((i % 2)) -eq 0 判断 i 除以 2 的余数是否为 0,若是则打印该数字,实现打印偶数的功能。

条件语法

-eq 两数值相等 (equal) 
-ne 两数值不等 (not equal) 
-gt n1 大于 n2 (greater than) 
-lt n1 小于 n2 (less than) 
-ge n1 大于等于 n2 (greater than or equal) 
-le n1 小于等于 n2 (less than or equal)

猜数字脚本

以下是一个简单的Bash猜数字比大小脚本:

猜数字,让用户输入一个数字,你给出一个随机数,猜对游戏结束,猜错给出提示。

限制10次?怎么做?

[root@www.yuchaoit.cn ~]$cat guess_num.sh
#!/bin/bash



target_num=$(( $RANDOM%100 + 1 ))


echo "欢迎使用猜数字游戏---v1版"

guess=0

while [ $guess -ne $target_num  ]

do

    read -p "输入你的数字:" guess
    # 判断输入是否合法,为纯数字
    if [[ ! $guess =~ ^[0-9]+$  ]]
        then
        echo "必须是纯数字,重写!"
        guess=0
        continue

    fi

    # 输入正确,是纯数字,数字判断,给一些提示
    if [ $guess -lt $target_num   ];then
        echo "太小了,往大了猜!"
    elif [ $guess -gt $target_num   ];then
        echo "太大了!往小了再猜!!!!"
    else
        echo "恭喜你,牛啊老弟"
    fi
done
[root@www.yuchaoit.cn ~]$

# 添加功能,v2,限制只能猜10次,并且每次提示,猜测第几次。

代码解释和使用说明

  • target_number=$((RANDOM % 100 + 1)):使用 RANDOM 环境变量生成一个随机数,RANDOM 是一个Bash内置的随机数生成器,范围是 0 到 32767。通过 % 100 + 1 运算将其范围限制在 1 到 100 之间。
  • guess=-1:初始化用户的猜测数字为 -1,这个值会在用户开始输入数字后更新。
  • while [ $guess -ne $target_number ]; do:使用 while 循环,只要用户的猜测不等于目标数字,就会一直循环。
  • read -p "请输入你的猜测: " guess:使用 read 命令提示用户输入一个数字,并将用户输入存储在 guess 变量中。
  • if [[! $guess =~ ^[0-9]+$ ]]; then:使用正则表达式 ^[0-9]+$ 检查用户输入是否为纯数字,如果不是,则提示用户输入有效数字并使用 continue 继续下一次循环。
  • if [ $guess -lt $target_number ]; thenif [ $guess -gt $target_number ]; then:使用条件判断,如果用户的猜测小于或大于目标数字,分别给出相应的提示。
  • else 部分:当用户猜对时,打印恭喜信息并结束循环。

这个脚本的使用方法很简单,你只需要将其保存为一个文件(例如 guess_game.sh),并赋予执行权限(chmod +x guess_game.sh),然后运行该文件(./guess_game.sh),即可开始猜数字游戏。

你可以根据需要对这个脚本进行扩展,例如添加猜测次数限制,当超过一定次数还未猜对时,游戏结束;或者增加不同的难度级别,改变随机数的范围等。

案例

猜数字比大小

猜数字大小程序开发(初版,还有很多bug!一步步优化!)


cat > num.sh<<'EOF'
# 结果
result=18
# 用户输入
read -p "请输入数字,猜大小:" num

if [ $result -eq $num ];then
    echo "猜对啦!你可真nb!"
elif [ $result -gt $num ];then
    echo "太小了,再猜!"
elif [ $result -lt $num ];then
    echo "太大了,再猜!"
fi
EOF

执行

image-20220616151942903

比较数字大小,美化结果

cat > beautiful_num.sh<<'EOF'
# 加载美化脚本
source /etc/init.d/functions

# 接收输入
read -p "please input num1:" num1
read -p "please input num2:" num2


# 条件判断测试
# 等于
[ $num1 -eq $num2 ] && action "-eq 等于OK" /bin/true || action "-eq NO" /bin/false

# 不等于
[ $num1 -ne $num2 ] && action "-ne 不等于OK" /bin/true || action "-ne NO" /bin/false

# 大于
[ $num1 -gt $num2 ] && action "-gt 大于OK" /bin/true || action "-gt NO" /bin/false

# 小于
[ $num1 -lt $num2 ] && action "-lt 小于OK" /bin/true || action "-lt NO" /bin/false

# 大于等于
[ $num1 -ge $num2 ] && action "-ge 大于等于OK" /bin/true || action "-ge NO" /bin/false

# 小于等于
[ $num1 -le $num2 ] && action "-le 小于等于OK" /bin/true || action "-le NO" /bin/false
EOF

扩展条件测试

在Bash中,[][[]]都是用于条件测试和模式匹配的结构,但它们在功能和使用上有一些区别,以下是详细解释:

[](test命令的简化形式)

  • 基本用途

    • 用于进行各种条件测试,例如检查文件属性、比较数值、判断字符串是否为空或相等。例如,[ -f file.txt ]用于检查file.txt是否为普通文件,[ 5 -gt 3 ]用于判断5是否大于3。
  • 操作符使用

    • []中使用比较操作符时,需要注意操作符和操作数之间要有空格分隔,否则会导致错误。例如,正确的写法是[ $a -eq 10 ],而不是[ $a -eq 10 ]
    • 对于字符串比较,[]使用=!=来判断是否相等或不相等。例如,[ "$str" = "hello" ]
  • 逻辑操作

    • 可以使用-a(与)和-o(或)来进行逻辑运算。例如,[ $a -gt 5 -a $a -lt 10 ]表示$a大于5且小于10。

[[]](扩展的条件测试)

  • 基本用途
    • 也是用于条件测试和模式匹配,功能比[]更强大,是Bash的扩展特性。
  • 操作符使用
    • 支持更多的比较操作符,例如><[[]]中可以直接用于字符串比较,并且按照字典序进行比较。例如,[[ "abc" < "abd" ]]返回真。
  • 逻辑操作
    • 可以使用&&(与)和||(或)进行逻辑运算,这与[]中的-a-o类似,但在使用上可能更符合习惯。例如,[[ $a -gt 5 && $a -lt 10 ]]
  • 模式匹配
    • 支持更高级的模式匹配功能,如正则表达式匹配。例如,[[ "hello world" =~ ^hello.* ]]可以匹配以hello开头的字符串。
    • 还支持=~操作符用于正则表达式匹配,这在处理复杂的字符串匹配场景时非常有用。
  • 变量扩展
    • [[]]中,变量扩展更加灵活。例如,[[ $str == he* ]]可以正确匹配以he开头的字符串,而在[]中可能需要使用[ "${str#he*}"!= "$str" ]来实现类似功能。

总结来说,[]是比较传统和基本的条件测试结构,适用于简单的条件判断和测试。[[]]是Bash的扩展特性,提供了更强大、更灵活的功能,特别是在字符串处理和模式匹配方面,更适合复杂的条件判断和脚本编写。在实际使用中,可以根据具体需求选择合适的结构。

练习题

判断整数

以下是一个Bash脚本,用于判断用户输入的内容是否为整数:

#!/bin/bash

# 提示用户输入一个数
read -p "请输入一个数: " input

# 使用正则表达式来判断输入是否为整数
if [[ $input =~ ^[0-9]+$ ]]; then
    echo "输入的是整数。"
else
    echo "输入的不是整数。"
fi

代码解释和使用说明

  • read -p "请输入一个数: " input:使用 read 命令提示用户输入一个数,并将用户输入存储在 input 变量中。
  • if [[ $input =~ ^[0-9]+$ ]]; then:这里使用了双中括号 [[ ]] 中的 =~ 运算符,用于进行正则表达式匹配。
    • ^[0-9]+$ 是一个正则表达式,其中:
      • ^ 表示匹配字符串的开始。
      • [0-9] 表示匹配数字 0 到 9 中的任意一个。
      • + 表示匹配前面的元素(即数字)一次或多次。
      • $ 表示匹配字符串的结束。
    • 所以,这个正则表达式整体的含义是:从字符串的开始到结束,全部由数字组成,这就是判断输入是否为整数的依据。
  • echo "输入的是整数。":如果输入匹配上述正则表达式,说明输入的是整数,打印相应的信息。
  • else 部分:如果输入不匹配,打印“输入的不是整数。”。

使用该脚本的步骤如下:

  1. 将上述代码保存为一个文件,例如 check_integer.sh
  2. 为该文件添加执行权限,使用命令 chmod +x check_integer.sh
  3. 运行该脚本,使用命令 ./check_integer.sh

你可以在这个基础上进行扩展,例如将这个判断封装在一个函数中,方便在其他脚本中调用,代码如下:

#!/bin/bash

# 定义一个函数来判断输入是否为整数
function is_integer() {
    local input="$1"
    if [[ $input =~ ^[0-9]+$ ]]; then
        return 0
    else
        return 1
    fi
}

# 提示用户输入一个数
read -p "请输入一个数: " input

# 调用函数进行判断
if is_integer "$input"; then
    echo "输入的是整数。"
else
    echo "输入的不是整数。"
fi

代码解释和使用说明

  • function is_integer() {...}:定义了一个名为 is_integer 的函数,它接受一个参数 $1,将其存储在 local input="$1" 中。
    • 如果输入匹配整数的正则表达式,函数使用 return 0 表示输入是整数。
    • 否则,使用 return 1 表示输入不是整数。
  • read -p "请输入一个数: " input:提示用户输入一个数,并存储在 input 变量中。
  • if is_integer "$input"; then:调用 is_integer 函数,并根据函数的返回值进行判断,如果返回值为 0,则输入是整数;如果返回值为 1,则输入不是整数。

通过将判断逻辑封装在函数中,可以提高代码的复用性和可维护性,方便在其他脚本中使用该函数进行整数判断。

判断参数个数

以下是一个简单的Bash脚本,用于判断传递给脚本的参数个数:

#!/bin/bash

# 获取传递给脚本的参数个数
num_params=$#

# 对参数个数进行判断
if [ $num_params -eq 0 ]; then
    echo "没有传递任何参数。"
elif [ $num_params -eq 1 ]; then
    echo "传递了一个参数。"
elif [ $num_params -eq 2 ]; then
    echo "传递了两个参数。"
else
    echo "传递了多个参数(大于 2 个)。"
fi

代码解释和使用说明

  • num_params=$#:使用 $# 特殊变量来获取传递给脚本的参数的数量。在Bash中,$# 表示传递给脚本的参数的个数。
  • if [ $num_params -eq 0 ]; then:使用条件判断来检查参数的数量是否等于 0。
    • 如果参数数量等于 0,打印“没有传递任何参数。”。
  • elif [ $num_params -eq 1 ]; then:如果参数数量等于 1,打印“传递了一个参数。”。
  • elif [ $num_params -eq 2 ]; then:如果参数数量等于 2,打印“传递了两个参数。”。
  • else 部分:如果参数数量大于 2,打印“传递了多个参数(大于 2 个)。”。

使用该脚本的步骤如下:

  1. 将上述代码保存为一个文件,例如 check_param_count.sh
  2. 为该文件添加执行权限,使用命令 chmod +x check_param_count.sh
  3. 可以有以下几种运行方式:
    • 不传递参数:./check_param_count.sh,会输出“没有传递任何参数。”。
    • 传递一个参数:./check_param_count.sh param1,会输出“传递了一个参数。”。
    • 传递两个参数:./check_param_count.sh param1 param2,会输出“传递了两个参数。”。
    • 传递多个参数:./check_param_count.sh param1 param2 param3,会输出“传递了多个参数(大于 2 个)。”。

你可以根据自己的需求对该脚本进行扩展,例如:

  • 当参数数量不符合要求时,给出错误提示并退出脚本。
  • 根据不同的参数数量执行不同的操作,代码示例如下: ```bash

    !/bin/bash

获取传递给脚本的参数个数

num_params=$#

对参数个数进行判断

if [ $num_params -eq 0 ]; then echo "没有传递任何参数,脚本需要至少一个参数。" exit 1 elif [ $num_params -eq 1 ]; then echo "传递了一个参数,执行操作 A。"

# 这里可以添加对一个参数的具体操作
param1=$1
echo "参数是:$param1"

elif [ $num_params -eq 2 ]; then echo "传递了两个参数,执行操作 B。"

# 这里可以添加对两个参数的具体操作
param1=$1
param2=$2
echo "参数是:$param1 和 $param2"

else echo "传递了多个参数(大于 2 个),执行操作 C。"

# 这里可以添加对多个参数的具体操作
echo "所有参数:$@"

fi

**代码解释和使用说明**:
- `exit 1`:当没有传递任何参数时,使用 `exit 1` 退出脚本,并返回错误代码 1,表示发生了错误。
- `param1=$1` 和 `param2=$2`:将第一个和第二个参数存储在变量 `param1` 和 `param2` 中,方便后续操作。
- `echo "所有参数:$@"`:使用 `$@` 特殊变量可以获取传递给脚本的所有参数列表,在参数数量大于 2 时打印出所有参数。


这样可以让脚本根据不同的参数数量做出不同的处理,使脚本更加灵活和实用。

### 判断用户的密码是否符合6位

> 方案1:利用变量的子字符串功能,判断字符串长度`${#变量}`

cat > user_pwd.sh<<'EOF' read -p "please input your pwd:" pwd

条件判断处理,利用变量的子字符串功能

[ ${#pwd} -ne 6 ] && echo "错误!密码必须是6位" || echo "正确!您的密码是:${pwd}" EOF


> 方案2:使用wc -L 参数

cat > pwd.sh <<'EOF' read -p "please input your pwd:" pwd

密码长度校验

pwd_len=$(echo $pwd|wc -L) [ $pwd_len -ne 6 ] && echo "错误!密码必须是6位" || echo "正确!您的密码是:${pwd}" EOF


### 用户登录脚本

以下是一个简单的Bash用户登录脚本示例,该脚本会从用户那里获取用户名和密码,并进行简单的验证:
```bash
#!/bin/bash

# 预设的用户名和密码(实际应用中应该使用更安全的存储方式,如数据库)
correct_username="admin"
correct_password="password123"

# 提示用户输入用户名和密码
read -p "请输入用户名: " input_username
read -s -p "请输入密码: " input_password
echo

# 进行验证
if [ "$input_username" = "$correct_username" ] && [ "$input_password" = "$correct_password" ]; then
    echo "登录成功!"
else
    echo "用户名或密码错误,请重试。"
fi

代码解释和使用说明

  • correct_username="admin"correct_password="password123":设置了预设的用户名和密码。在实际应用中,这些信息应该存储在更安全的地方,比如数据库,而不是硬编码在脚本中。
  • read -p "请输入用户名: " input_username:使用 read 命令提示用户输入用户名,并将其存储在 input_username 变量中。
  • read -s -p "请输入密码: " input_password:使用 read -s 命令提示用户输入密码,-s 选项会隐藏用户输入,避免密码显示在屏幕上。
  • echo:添加一个空的 echo 语句,使输入密码后光标移到下一行,以保持输出的美观。
  • if [ "$input_username" = "$correct_username" ] && [ "$input_password" = "$correct_password" ]; then:使用 if 语句结合逻辑与运算符 && 来检查输入的用户名和密码是否与预设的匹配。
    • [ "$input_username" = "$correct_username" ]:检查用户名是否正确。
    • [ "$input_password" = "$correct_password" ]:检查密码是否正确。
    • 只有当用户名和密码都正确时,才会输出“登录成功!”。
  • else 部分:如果用户名或密码错误,输出“用户名或密码错误,请重试。”。

以下是该脚本的使用方法:

  1. 将上述代码保存为一个文件,例如 login_script.sh
  2. 为该文件添加执行权限,使用命令 chmod +x login_script.sh
  3. 运行该脚本,使用命令 ./login_script.sh

为了提高该脚本的安全性和实用性,你可以进行以下扩展:

  • 添加用户输入验证:确保用户输入不为空,避免输入错误。 ```bash

    !/bin/bash

预设的用户名和密码(实际应用中应该使用更安全的存储方式,如数据库)

correct_username="admin" correct_password="password123"

提示用户输入用户名和密码

read -p "请输入用户名: " input_username read -s -p "请输入密码: " input_password echo

验证输入是否为空

if [ -z "$input_username" ] || [ -z "$input_password" ]; then echo "用户名或密码不能为空,请重试。" exit 1 fi

进行验证

if [ "$input_username" = "$correct_username" ] && [ "$input_password" = "$correct_password" ]; then echo "登录成功!" else echo "用户名或密码错误,请重试。" fi

**代码解释和使用说明**:
- `if [ -z "$input_username" ] || [ -z "$input_password" ]; then`:使用 `-z` 选项检查用户名或密码是否为空。
  - `-z` 用于检查字符串长度是否为零,如果为空,输出错误信息并使用 `exit 1` 退出脚本。


- **限制登录尝试次数**:限制用户尝试登录的次数,防止暴力破解。
```bash
#!/bin/bash

# 预设的用户名和密码(实际应用中应该使用更安全的存储方式,如数据库)
correct_username="admin"
correct_password="password123"
max_attempts=3
attempts=0

# 循环进行登录尝试
while [ $attempts -lt $max_attempts ]; do
    # 提示用户输入用户名和密码
    read -p "请输入用户名: " input_username
    read -s -p "请输入密码: " input_password
    echo

    # 验证输入是否为空
    if [ -z "$input_username" ] || [ -z "$input_password" ]; then
        echo "用户名或密码不能为空,请重试。"
        continue
    fi

    # 进行验证
    if [ "$input_username" = "$correct_username" ] && [ "$input_password" = "$correct_password" ]; then
        echo "登录成功!"
        exit 0
    else
        echo "用户名或密码错误,请重试。"
        attempts=$((attempts + 1))
    fi
done

echo "超过最大尝试次数,请稍后再试。"
exit 1

代码解释和使用说明

  • max_attempts=3:设置最大尝试次数为 3 次。
  • attempts=0:初始化尝试次数为 0。
  • while [ $attempts -lt $max_attempts ]; do:使用 while 循环,只要尝试次数小于最大尝试次数,就允许用户继续尝试登录。
  • attempts=$((attempts + 1)):每次尝试失败后,将尝试次数加 1。
  • echo "超过最大尝试次数,请稍后再试。":当尝试次数超过最大次数时,输出错误信息并使用 exit 1 退出脚本。

这些扩展可以使登录脚本更加安全和完善,你可以根据具体需求进一步调整和扩展该脚本。

3.基于字符串判断

比较操作 操作符 示例 说明
相等 = 或 == if [ "$str1" = "$str2" ]; then echo "相等"; fi $str1 等于 $str2 时,条件为真,使用 == 操作符在某些情况下也可行,但 = 更常用且符合标准。使用双引号包裹变量,可防止变量为空时的语法错误。
不相等 != if [ "$str1"!= "$str2" ]; then echo "不相等"; fi $str1 不等于 $str2 时,条件为真。
长度为零 -z if [ -z "$str" ]; then echo "字符串长度为零"; fi $str 的长度为 0,条件为真。常用于检查变量是否为空。
长度不为零 -n if [ -n "$str" ]; then echo "字符串长度不为零"; fi $str 的长度不为 0,条件为真。可用于检查变量是否包含有效内容。

以下是使用这些操作符的示例脚本:

#!/bin/bash

str1="hello"
str2="world"
str3=""

# 相等比较
if [ "$str1" = "$str2" ]; then
    echo "str1 等于 str2"
else
    echo "str1 不等于 str2"
fi

# 不相等比较
if [ "$str1"!= "$str2" ]; then
    echo "str1 不等于 str2"
else
    echo "str1 等于 str2"
fi

# 长度为零检查
if [ -z "$str3" ]; then
    echo "str3 长度为零"
else
    echo "str3 长度不为零"
fi

# 长度不为零检查
if [ -n "$str1" ]; then
    echo "str1 长度不为零"
else
    echo "str1 长度为零"
fi

代码解释和使用说明

  • if [ "$str1" = "$str2" ]; then...:使用 = 操作符检查 str1str2 是否相等,由于它们不相等,将输出“str1 不等于 str2”。
  • if [ "$str1"!= "$str2" ]; then...:使用 != 操作符检查 str1str2 是否不相等,将输出“str1 不等于 str2”。
  • if [ -z "$str3" ]; then...:使用 -z 操作符检查 str3 的长度是否为零,由于 str3 为空字符串,将输出“str3 长度为零”。
  • if [ -n "$str1" ]; then...:使用 -n 操作符检查 str1 的长度是否不为零,由于 str1 不为空,将输出“str1 长度不为零”。

在实际的脚本编写中,这些操作符的使用非常灵活,例如:

#!/bin/bash

# 检查环境变量是否设置
if [ -z "$JAVA_HOME" ]; then
    echo "JAVA_HOME 环境变量未设置,请设置该环境变量。"
else
    echo "JAVA_HOME 已设置:$JAVA_HOME"
fi

# 检查用户输入是否为指定字符串
read -p "请输入一个字符串: " user_input
if [ "$user_input" = "quit" ]; then
    echo "用户选择退出。"
    exit 0
else
    echo "用户输入:$user_input"
fi

代码解释和使用说明

  • if [ -z "$JAVA_HOME" ]; then...:检查 JAVA_HOME 环境变量是否未设置,若未设置则给出提示。
  • read -p "请输入一个字符串: " user_input:提示用户输入一个字符串并存储在 user_input 中。
  • if [ "$user_input" = "quit" ]; then...:检查用户输入是否为“quit”,若是则退出脚本,否则输出用户输入的内容。

此外,还可以在复杂的逻辑中使用这些操作符,如:

#!/bin/bash

str1="yes"
str2="no"
str3="maybe"

# 复杂逻辑判断
if [ "$str1" = "yes" ] && [ -n "$str2" ] || [ "$str3" = "maybe" ]; then
    echo "满足复杂逻辑条件"
else
    echo "不满足复杂逻辑条件"
fi

代码解释和使用说明

  • if [ "$str1" = "yes" ] && [ -n "$str2" ] || [ "$str3" = "maybe" ]; then...:使用逻辑与 && 和逻辑或 || 运算符。
    • str1 等于“yes”且 str2 长度不为零,或者 str3 等于“maybe”时,条件为真,将输出“满足复杂逻辑条件”。

这些字符串比较操作符和逻辑运算符的组合可以帮助你在Bash脚本中进行丰富的条件判断,以实现各种功能。

系统自带脚本参考

image-20220616223214703

以及一段关于mysql的脚本

233       # pid-file exists, the server process doesn't.
234       # it must've crashed, and mysqld_safe will restart it
235       if test -n "$crash_protection"; then
236         crash_protection=""
237         sleep 5
238         continue  # Check again.
239       fi

这里就是判断,当该crash_protection变量非空时,将其置空

这里的逻辑我们不用过多关注,从注释可以得知

该代码作用是,当mysql的pid-file存在,但是mysql进程不存在,这就证明mysql异常挂掉了,mysql应该重启。

练习

简单等于、不等于符号

[root@yuchaoit666 ~]#[ 10 == 10 ] && echo "yes" || echo "no"
yes
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ 10 != 10 ] && echo "yes" || echo "no"
no
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ 10 != 5 ] && echo "yes" || echo "no"
yes

条件参数-z和-n相反测试

[root@yuchaoit666 ~]#name="yuchao666"
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
# -z 字符串为空,才为真
[root@yuchaoit666 ~]#[ -z $name ] && echo "true" || echo "false"
false
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ -z $name2 ] && echo "true" || echo "false"
true
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ -n $name ] && echo "true" || echo "false"
true
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ -n $name2 ] && echo "true" || echo "false"
true
[root@yuchaoit666 ~]#

模拟开发登录程序

接收用户输入,和密码文件对比,判断是否登录成功。

现有账号密码
yuchao01
chaoge666
cat >user_login.sh<<'EOF'
read -p "please input username:" username
read -p "please input pwd:" pwd

[ $username == "yuchao01" -a $pwd == "chaoge666" ] && echo "登录成功" || echo "账号密码错误" 
EOF

4. 逻辑操作符

逻辑运算,也就是生活里的 真、假概念

! 取反,也就是结果相反的值

-a 是“与”的意思(等同 && 和and),要求,左右两个逻辑值都为真,结果才为真,否则为假

-o 是或者的意思,(or 和 ||),左右两个逻辑,只要有一个真,结果就为真

结果为真,对应计算机数字是1

结果为假,计算机数字为0

注意:选用不同的语法,对应的测试符号不一样!!!
参数 解释 案例
-a 左右两边条件同时为真时,为true [ 6 -eq 6 -a 8 -gt 3 ]
-o 左右两边条件有一个为真,就为true [ 1 -gt 1 -o 2 -eq 2 ]
! 结果取反
结果取反
[root@yuchaoit666 ~]#[ 1 -eq 1 ] && echo true || echo false
true
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ !  1 -eq 1 ] && echo true || echo false
false


或运算
[root@yuchaoit666 ~]#[ 1 -eq 1 -o 2 -gt 2 ] && echo yes || echo no
yes
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ 1 -gt 1 -o 2 -gt 2 ] && echo yes || echo no
no
[root@yuchaoit666 ~]#[ 1 -gt 1 -o 2 -lt 2 ] && echo yes || echo no
no
[root@yuchaoit666 ~]#[ 1 -gt 1 -o 2 -eq 2 ] && echo yes || echo no
yes


并且运算
[root@yuchaoit666 ~]#[ 6 -eq 6 -a 8 -gt 3 ] && echo true || echo no
true
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#
[root@yuchaoit666 ~]#[ 6 -eq 6 -a 8 -lt 3 ] && echo true || echo no
no
Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2025-01-21 11:45:06

results matching ""

    No results matching ""