一.Shell条件测试操作概述

Shell脚本中的条件测试是控制程序流程的基础,主要通过测试命令和操作符来实现。以下是主要的条件测试操作:

测试命令

  1. test命令
test expression

[ expression ]
  1. [[ ]] 扩展测试命令 (bash等现代shell支持)
[[ expression ]]
  1. (( )) 算术测试 (bash等支持)
(( arithmetic-expression ))

文件测试操作符

  • -e file: 文件是否存在
  • -f file: 是普通文件
  • -d file: 是目录
  • -r file: 可读
  • -w file: 可写
  • -x file: 可执行
  • -s file: 文件大小不为0
  • -L file: 是符号链接
  • -nt / -ot: 文件新旧比较

示例:

if [ -f "/path/to/file" ]; then
    echo "文件存在"
fi

字符串测试操作符

  • -z string: 字符串长度为0
  • -n string: 字符串长度非0
  • str1 = str2: 字符串相等
  • str1 != str2: 字符串不等
  • str1 < str2: 按字典顺序str1在str2前
  • str1 > str2: 按字典顺序str1在str2后

示例:

if [ "$var" = "hello" ]; then
    echo "变量等于hello"
fi

数值比较操作符

  • -eq: 等于
  • -ne: 不等于
  • -gt: 大于
  • -ge: 大于等于
  • -lt: 小于
  • -le: 小于等于

示例:

if [ "$a" -gt "$b" ]; then
    echo "a大于b"
fi

逻辑操作符

  • !: 非
  • -a: 与 (AND)
  • -o: 或 (OR)
  • &&: 逻辑与 (在[[ ]]中使用)
  • ||: 逻辑或 (在[[ ]]中使用)

示例:

if [ "$a" -gt 0 -a "$a" -lt 10 ]; then
    echo "a在0到10之间"
fi

组合条件

使用括号分组条件:

if [ \( "$a" -gt 0 \) -a \( "$a" -lt 10 \) ]; then
    echo "a在0到10之间"
fi

在[[ ]]中更简洁:

if [[ $a > 0 && $a < 10 ]]; then
    echo "a在0到10之间"
fi

现代shell的增强测试

bash等现代shell支持:

  • 模式匹配:[[ $var == *.txt ]]
  • 正则匹配:[[ $var =~ ^[0-9]+$ ]]
  • 无需引号的变量扩展
  • 更自然的逻辑运算符(&&, ||)

示例:

if [[ "$filename" == *.txt ]]; then
    echo "这是一个文本文件"
fi

条件测试是shell脚本编程的核心部分,合理使用可以使脚本更加健壮和灵活。

二.if条件语句

if条件语句是Shell脚本中进行条件判断和流程控制的核心结构,它允许根据测试条件的真假执行不同的代码块。

基本语法结构

1. 单分支if语句

if [ 条件测试 ]; then
 # 条件为真时执行的命令
fi

if条件语句逻辑图

Shell编程只条件语句_操作符

示例:

if [ -f "file.txt" ]; then
    echo "file.txt存在"
fi

2. 双分支if-else语句

if [ 条件测试 ]; then
    # 条件为真时执行的命令
else
    # 条件为假时执行的命令
fi

if双分支语句逻辑图

Shell编程只条件语句_bash_02

示例:

if [ -d "/path/to/dir" ]; then
    echo "目录存在"
else
    echo "目录不存在"
fi

3. 多分支if-elif-else语句

if [ 条件测试1 ]; then
    # 条件1为真时执行的命令
elif [ 条件测试2 ]; then
    # 条件2为真时执行的命令
else
    # 所有条件都为假时执行的命令
fi

if多分支语句逻辑图

Shell编程只条件语句_bash_03


示例:

if [ "$1" -gt 100 ]; then
    echo "大于100"
elif [ "$1" -gt 50 ]; then
    echo "大于50但小于等于100"
else
    echo "小于等于50"
fi

条件测试的多种形式

1. 使用test命令或[ ]

if test 条件; then
    # ...
fi

# 或者
if [ 条件 ]; then
    # ...
fi

2. 使用[[ ]] (bash等现代shell支持)

if [[ 条件 ]]; then
    # ...
fi

3. 使用(( ))进行算术比较

if (( 算术表达式 )); then
    # ...
fi

示例:

if (( $a > $b )); then
    echo "a大于b"
fi

4. 直接使用命令返回值

if 命令; then
    # 命令返回0(成功)时执行
fi

示例:

if grep -q "pattern" file.txt; then
    echo "找到匹配模式"
fi

复合条件

1. 逻辑与(AND)

if [ 条件1 ] && [ 条件2 ]; then
    # 两个条件都为真时执行
fi

# 或者使用[[ ]]
if [[ 条件1 && 条件2 ]]; then
    # ...
fi

2. 逻辑或(OR)

if [ 条件1 ] || [ 条件2 ]; then
    # 任一条件为真时执行
fi

# 或者使用[[ ]]
if [[ 条件1 || 条件2 ]]; then
    # ...
fi

嵌套if语句

if [ 条件1 ]; then
    if [ 条件2 ]; then
        # 两个条件都为真时执行
    fi
fi

特殊用法

1. 单行if语句

if [ 条件 ]; then 命令; fi

# 或者
[ 条件 ] && 命令1 || 命令2

示例:

[ -f file.txt ] && echo "存在" || echo "不存在"
case $变量 in
    模式1)
        命令1
        ;;
    模式2)
        命令2
        ;;
    *)
        默认命令
        ;;
esac

注意事项

  1. [ 是一个命令,与后面的参数之间必须有空格
  2. ] 前必须有空格
  3. 字符串比较时变量要用引号括起来,防止空变量或含空格变量
  4. 数值比较使用-eq, -ne等操作符,而不是==, !=
  5. 在[[ ]]中可以使用更自然的比较运算符(>, <等)

if条件语句是Shell脚本中实现逻辑控制的基础,熟练掌握其各种用法对于编写健壮的脚本至关重要。

三.case分支语句概述

case语句是Shell脚本中用于多条件分支选择的结构,它比多个if-elif语句更简洁高效,特别适合处理一个变量与多个模式匹配的场景。

基本语法结构

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

case语句逻辑图

Shell编程只条件语句_操作符_04

关键组成部分

  1. 变量:被测试的变量或表达式
  2. 模式:用于匹配的模式,可以使用通配符
  3. 命令序列:匹配成功后执行的命令
  4. ;;:表示该模式对应的命令序列结束
  5. \*):默认情况,匹配所有其他情况
  6. esaccase语句的结束标记(case的反写)

模式匹配特性

  • 支持通配符:
  • *:匹配任意字符
  • ?:匹配单个字符
  • [ ]:匹配括号内的任一字符
  • 支持|表示"或"关系
  • 模式匹配是按顺序进行的,第一个匹配的模式会被执行

常见用法示例

1. 基本字符串匹配

#!/bin/bash

read -p "输入水果名称: " fruit

case $fruit in
    apple)
        echo "这是苹果"
        ;;
    banana)
        echo "这是香蕉"
        ;;
    orange|lemon)
        echo "这是柑橘类水果"
        ;;
    *)
        echo "未知水果"
        ;;
esac

2. 使用通配符匹配

#!/bin/bash

read -p "输入文件名: " filename

case $filename in
    *.txt)
        echo "文本文件"
        ;;
    *.jpg|*.png)
        echo "图片文件"
        ;;
    *)
        echo "其他类型文件"
        ;;
esac

3. 系统服务管理脚本示例

#!/bin/bash

case $1 in
    start)
        echo "启动服务..."
        # 启动命令
        ;;
    stop)
        echo "停止服务..."
        # 停止命令
        ;;
    restart)
        echo "重启服务..."
        # 重启命令
        ;;
    status)
        echo "查看服务状态..."
        # 状态检查命令
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

4. 匹配数字范围

#!/bin/bash

read -p "输入分数(0-100): " score

case $score in
    9[0-9]|100)
        echo "优秀"
        ;;
    8[0-9])
        echo "良好"
        ;;
    7[0-9])
        echo "中等"
        ;;
    6[0-9])
        echo "及格"
        ;;
    [0-9]|[1-5][0-9])
        echo "不及格"
        ;;
    *)
        echo "无效分数"
        ;;
esac

高级用法

1. 使用正则表达式(bash 3.0+)

#!/bin/bash

read -p "输入日期(YYYY-MM-DD): " date

case $date in
    ^[0-9]{4}-[0-9]{2}-[0-9]{2}$)
        echo "有效日期格式"
        ;;
    *)
        echo "无效日期格式"
        ;;
esac

2. 嵌套case语句

#!/bin/bash

read -p "输入文件类型和操作: " type op

case $type in
    text)
        case $op in
            edit) echo "编辑文本文件" ;;
            view) echo "查看文本文件" ;;
            *) echo "无效的文本文件操作" ;;
        esac
        ;;
    image)
        case $op in
            show) echo "显示图片" ;;
            edit) echo "编辑图片" ;;
            *) echo "无效的图片操作" ;;
        esac
        ;;
    *)
        echo "未知文件类型"
        ;;
esac

注意事项

  1. 每个命令序列必须以;;结束(除了最后一种情况)
  2. 模式匹配是大小写敏感
  3. *)默认情况不是必须的,但建议总是包含
  4. 可以使用;&(bash 4.0+)来继续执行下一个模式的命令(不中断)
  5. 可以使用;;&(bash 4.0+)来继续测试后续模式

与if语句的比较

特性

case语句

if语句

适用场景

单一变量多值匹配

复杂条件判断

可读性

多条件时更清晰

简单条件时更直观

性能

通常更快

相对较慢

模式匹配

支持通配符

需要额外测试命令

复杂条件

不适合

适合处理复杂逻辑

case语句是Shell脚本中处理多分支选择的强大工具,特别适合命令选项解析、文件类型判断等场景。