Shell编程条件语句:条件测试操作、if语句、case语句



条件测试操作

Shell 环境通过命令执行后的返回状态值($?)来判断是否执行成功。当返回值为 0(真,true)时表示成功,返回值为非 0 值(假,false)时表示失败或异常。

test 命令可以对特定条件进行测试,并根据返回值来判断条件是否成立($? 返回值为 0 表示条件成立)。

格式:

  • 格式一:test 条件表达式

  • 格式二(简写):[ 条件表达式 ]

    注意:方括号[ 和 ]与条件表达式之间需要至少一个空格进行分隔。

文件测试

格式:

  • [ 操作符 文件或目录 ]

常用操作符:

  • -e:测试目录或文件是否存在 (Exist)
  • -d:测试是否为目录 (Directory)
  • -f:测试是否为文件 (File)
  • -r:测试当前用户是否有权限读取 (Read)
  • -w:测试当前用户是否有权限写入(Write)
  • -x:测试是否设置有可执行(Excute)权限。
  • -L:测试是否为符号链接

整数值比较

格式:

  • [ 整数变量1 操作符 整数变量2 ]

常用操作符:

  • -eq:等于 == (等于equal)
  • -ne:不等于 != (not equal)
  • -gt:大于 \> (大于greater)
  • -lt:小于 \< (小于les)
  • -le:小于等于 <=
  • -ge:大于等于 >=
test 1 -eq 1
echo $?

字符串比较

格式 1:

  • [ 字符串1 = 字符串2 ][ 字符串1 == 字符串2 ]
  • [ 字符串1 != 字符串2 ]
[root@localhost ~]# test yht == dxl
[root@localhost ~]# echo $?
1
[root@localhost ~]# test yht == yht
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ dxl == wujian ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ wujian == wujian ]
[root@localhost ~]# echo $?
0

格式 2:

  • [ -z "字符串" ]:检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串。
  • [ -n "字符串" ]:检查是否有字符串存在。(使用引号,防止扰乱空格)

逻辑测试

格式 1:

  • [ 表达式1 ] 操作符 [ 表达式2 ]

格式 2:

  • 命令1 操作符 命令2

常用操作符:

  • -a&&:逻辑与,表示“而且”,前后条件需都成立。
  • -o||:逻辑或,表示“或者”,只需前后条件中一个成立。
  • !:逻辑否。
a=5
[ $a -ne 1 ] && [ $a != 2 ]  
# 等同于 
[ $a -ne 1 -a $a != 2 ] # 不用两个中括号

注意

  • &&|| 操作符能够正常存在于 [[ ]] 条件判断结构中,但如果出现在 [ ] 结构中,会报错。

单双中括号

  • 单中括号 []
    • 功能:用于测试表达式的真假,是一种命令,将测试表达式视为参数。
    • 使用要求
      • 测试表达式中的各个部分需要用空格分隔。
      • 变量通常需要用双引号引起来,以防止空值或特殊字符引发错误。
    • 注意事项
      • [ $var -eq 1 ] 可能会因为 $var 为空而导致语法错误,而 [ "$var" -eq 1 ] 是正确的写法。
      • 单中括号的表达式有限,不支持复杂的模式匹配或正则表达式。
  • 双中括号 [[ ]]
    • 功能:也用于测试表达式的真假,但支持更复杂的表达式测试。
    • 额外特性
      • 支持模式匹配、字符串操作、正则表达式等高级特性。
      • 自动识别和处理变量中的空格,无需显式引用变量。
  • 使用建议:由于双中括号功能更强大,建议在编写脚本时优先使用双中括号 [[ ]]

示例

[[ $a != 1 && $a != 2 ]]
[[ 2 ­-lt 3 ]] && echo true || echo false
[[ 2 ­-ge 3 ]] && echo true || echo false

综合示例:检测指定IP地址或主机是否在线

vim pinghost.sh

#!/bin/bash
ping -c 3 -i 0.5 -W 2 $1 &> /dev/null && echo "$1 online" || echo "$1 off"

[root@localhost ~]# sh ip.sh 192.168.233.21
192.168.233.21 online

# 解释:
-c 3:发送3个ICMP请求包(Ping的次数)。
-i 0.5:每个Ping请求之间间隔0.5秒。
-W 2:等待每个Ping响应的超时时间为2秒。(-w:多少秒后停止 ping 命令操作)
$1:脚本执行时传入的第一个参数,即目标IP地址或主机名。
&> /dev/null:将ping命令的输出重定向到/dev/null,即忽略输出结果,只关心命令的返回值。
&& echo "$1 online":
&& 是逻辑与运算符,表示如果前面的ping命令执行成功(即返回值为0),则执行echo "$1 online",表示目标主机在线。
|| echo "$1 off":
|| 是逻辑或运算符,表示如果前面的ping命令执行失败(即返回值非0),则执行echo "$1 off",表示目标主机不在线。

if 语句

单分支 if 语句

格式:

if 条件测试操作
then
  命令序列
fi

示例:

if [ 3 -gt 2 ]; 
then 
  echo "ok"; 
fi
[ 3 -gt 2 ] && echo "ok"

双分支 if 语句

格式:

if 条件测试操作
then
  命令序列 1
else
  命令序列 2
fi

示例:

vim pinghost1.sh
#!/bin/bash
ping -c 3 -i 0.5 -W 2 $1 &> /dev/null
if [ $? -eq 0 ]
then
  echo "$1 online"
else
  echo "$1 off"
fi

多分支 if 语句

格式:

if 条件测试操作 1
then
  命令序列 1
elif 条件测试操作 2
then
  命令序列 2
[else]
  [命令序列 3]
fi

示例:

vim score.sh
#!/bin/bash
read -p "请输入您的分数(0-100): " score
if [ $score -ge 85 ] && [ $score -le 100 ]
then
  echo "$score 分,优秀!"
elif [ $score -ge 70 ] && [ $score -le 84 ]
then
  echo "$score 分,合格!"
else
  echo "$score 分,不合格!"
fi

双小括号

$(()) 语法说明

在 Bash 中,$(( )) 语法用于进行算术运算。

示例

判断变量 num 是否为偶数。假设变量 num 已经通过 read 命令定义为一个整数:

read -p "请输入一个数字: " num
if [ $(($num % 2)) -eq 0 ]; then
    echo "$num 是偶数"
else
    echo "$num 是奇数"
fi

解析

  • $(( )) 语法
    • Bash 中的算术运算符,可以执行加、减、乘、除、取模等操作。
    • 当其中包含变量时,Bash 会自动解析变量的值并进行运算。
  • 余数计算
    • 此例中,表达式 $(($num % 2)) 计算 num 除以 2 的余数。
    • 如果余数为 0,表示 num 是一个偶数。
  • 使用场景$(( )) 适用于需要进行算术运算的情况,常用于判断、循环等场景。
  • 自动解析:Bash 在执行 $(($num % 2)) 时,会自动将变量 num 的值替换到表达式中,并进行计算。

case 语句

格式:

case 变量值 in
  模式 1)
    命令序列 1
    ;;
  模式 2)
    命令序列 2
    ;;
  ……
  * )
    默认命令序列
esac

使用 case 分支语句的特点:

  1. case 行尾必须为单词 in,每一模式必须以右括号 ) 结束。
  2. 双分号 ;; 表示命令序列的结束。
  3. 模式字符串中,可以用方括号表示一个连续的范围,如 [0-9];还可以用竖杠符号 | 表示或,如 A|B
  4. 最后的 *) 表示默认模式,其中的 * 相当于通配符。

示例:

vim score1.sh
#!/bin/bash
read -p "请输入您的分数(0-100): " score
[[ $score -ge 80 && $score -le 100 ]] && a="great"
[[ $score -ge 60 && $score -lt 80 ]] && a="standard"
[[ $score -ge 0 && $score -lt 60 ]] && a="false"
case $score in
  great)
    echo "$score 分,优秀!"
    ;;
  standard)
    echo "$score 分,合格!"
    ;;
  false)
    echo "$score 分,不合格!"
    ;;
  *)
    echo "输入有误!"
esac
vim /etc/init.d/firewalld.sh
case $1 in
  start)
    echo -n "正在启动 firewalld 服务 ... "
    systemctl start firewalld.service
    echo "OK"
    ;;
  stop)
    echo -n "正在停止 firewalld 服务 ... "
    pkill "firewalld" &> /dev/null
    echo "OK"
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  status)
    if pgrep "firewalld" &>/dev/null ; then
      echo "firewalld 服务已经启动."
    else
      echo "firewalld 服务已经停止."
    fi
    ;;
  * )
    echo "用法: $0 {start|stop|status|restart}"
esac

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值