菜鸟教程 -- 学的不仅是技术,更是梦想!

Linux 教程
(追記) (追記ここまで)

Shell test 命令

test 命令是 Shell 内置的条件判断工具,用于评估表达式并返回布尔值(真/假),它通常与 if 语句结合使用,是 Shell 脚本中实现逻辑控制的基础。

Shell 中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

语法格式

test EXPRESSION
# 或
[ EXPRESSION ] # 注意方括号内必须有空格

文件测试操作

test 命令最常用于检查文件属性,以下是常用文件测试选项:

操作符 描述 示例
-e 文件是否存在 [ -e file.txt ]
-f 是普通文件 [ -f /path/to/file ]
-d 是目录 [ -d /path/to/dir ]
-r 可读 [ -r file.txt ]
-w 可写 [ -w file.txt ]
-x 可执行 [ -x script.sh ]
-s 文件大小 >0 [ -s logfile ]
-L 是符号链接 [ -L symlink ]

示例脚本:

实例

#!/bin/bash

file="/etc/passwd"

if [ -e "$file" ]; then
echo "$file 存在"
if [ -r "$file" ]; then
echo "并且可读"
fi
else
echo "$file 不存在"
fi

输出结果为:

/etc/passwd 存在
并且可读

字符串比较

test 提供了多种字符串比较方式:

操作符 描述 示例
-z STRING 字符串为空 [ -z "$var" ]
-n STRING 字符串非空 [ -n "$var" ]
STRING1 = STRING2 字符串相等 [ "$var1" = "$var2" ]
STRING1 != STRING2 字符串不等 [ "$var1" != "$var2" ]

重要提示:字符串变量应该总是用双引号括起来,防止空变量导致语法错误。

示例:

实例

#!/bin/bash

read -p "输入用户名: " username

if [ -z "$username" ]; then
echo "错误:用户名不能为空"
exit 1
elif [ "$username" = "root" ]; then
echo "警告:不建议使用root账户"
else
echo "欢迎, $username"
fi

执行后,我们在终端输入 runoob,输出结果类似如下:

输入用户名: runoob
欢迎, runoob

数值比较

对于数值比较,test 使用不同的操作符:

操作符 描述 示例
-eq 等于 [ "$a" -eq "$b" ]
-ne 不等于 [ "$a" -ne "$b" ]
-gt 大于 [ "$a" -gt "$b" ]
-ge 大于或等于 [ "$a" -ge "$b" ]
-lt 小于 [ "$a" -lt "$b" ]
-le 小于或等于 [ "$a" -le "$b" ]

示例:

实例

#!/bin/bash

read -p "输入年龄: " age

if [ "$age" -lt 0 ]; then
echo "年龄不能为负数"
elif [ "$age" -lt 18 ]; then
echo "未成年人"
elif [ "$age" -ge 18 ] && [ "$age" -lt 60 ]; then
echo "成年人"
else
echo "老年人"
fi

执行后,我们在终端输入 12,输出结果类似如下:

输入年龄: 12
未成年人

逻辑操作符

test 支持逻辑组合:

操作符 描述 示例
! 逻辑非 [ ! -f "$file" ]
-a 逻辑与 [ "$a" -eq 1 -a "$b" -eq 2 ]
-o 逻辑或 [ "$a" -eq 1 -o "$b" -eq 2 ]

现代推荐写法:使用 &&|| 替代 -a-o,更符合 POSIX 标准:

实例

[ "$a" -eq 1 ] && [ "$b" -eq 2 ] # 与
[ "$a" -eq 1 ] || [ "$b" -eq 2 ] # 或

高级用法:[[ ]] 和 (( ))

Bash 提供了更强大的测试语法:

双括号 [[ ]]

  • 支持模式匹配:[[ "$var" == *.txt ]]
  • 支持正则表达式:[[ "$var" =~ ^[0-9]+$ ]]
  • 更安全的字符串处理

算术比较 (( ))

  • 专为数值比较设计:(( a > b ))
  • 支持更复杂的算术表达式

示例:

实例

if [[ "$file" == *.log ]]; then
echo "这是日志文件"
fi

if (( $count > 10 )); then
echo "数量超过10"
fi

实际应用示例

1. 检查服务是否运行

实例

#!/bin/bash

service="nginx"

if systemctl is-active --quiet "$service"; then
echo "$service 正在运行"
else
echo "$service 未运行"
# 可以添加启动服务的命令
fi

2. 备份文件检查

实例

#!/bin/bash

backup_file="/backups/data_$(date +%Y%m%d).tar.gz"

if [ ! -f "$backup_file" ]; then
echo "错误:备份文件 $backup_file 不存在"
exit 1
elif [ ! -s "$backup_file" ]; then
echo "警告:备份文件为空"
else
echo "备份验证成功"
fi

常见错误与调试技巧

  1. 缺少空格:[ "$a"="$b" ] 是错误的,正确是 [ "$a" = "$b" ]
  2. 未引用的变量:[ -f $file ] 应该为 [ -f "$file" ]
  3. 混淆字符串和数值比较:使用 = 比较字符串,-eq 比较数值

调试技巧:在脚本开头添加 set -x 开启调试模式,或使用 echo 打印测试表达式:

实例

echo "测试表达式: [ $a -eq $b ]"
[ "$a" -eq "$b" ] && echo "成立" || echo "不成立"
AI 思考中...

5 篇笔记 写笔记

  1. #0

    Balcon

    you***[email protected]

    101

    符号含义:

    1. eq (equal的缩写),表示等于为真

    2. ne (not equal的缩写),表示不等于为真

    3. gt (greater than的缩写),表示大于为真

    4. ge (greater&equal的缩写),表示大于等于为真

    5. lt (lower than的缩写),表示小于为真

    6. le (lower&equal的缩写),表示小于等于为真

    Balcon

    you***[email protected]

    8年前 (2018年10月28日)
  2. #0

    开心小不点儿

    swj***[email protected]

    54
    result=$[a + b]

    等同于:

    result=`expr $a + $b `

    开心小不点儿

    swj***[email protected]

    8年前 (2019年01月18日)
  3. #0

    shell 判断文件夹或文件是否存在

    文件夹不存在则创建

    if [ ! -d "/data/" ];then
     mkdir /data
     else
     echo "文件夹已经存在"
    fi

    文件存在则删除

    if [ ! -f "/data/filename" ];then
     echo "文件不存在"
     else
     rm -f /data/filename
    fi

    判断文件夹是否存在

    if [ -d "/data/" ];then
     echo "文件夹存在"
     else
     echo "文件夹不存在"
    fi

    判断文件是否存在

    if [ -f "/data/filename" ];then
     echo "文件存在"
     else
     echo "文件不存在"
    fi

    文件比较符

    -e 判断对象是否存在
    -d 判断对象是否存在,并且为目录
    -f 判断对象是否存在,并且为常规文件
    -L 判断对象是否存在,并且为符号链接
    -h 判断对象是否存在,并且为软链接
    -s 判断对象是否存在,并且长度不为0
    -r 判断对象是否存在,并且可读
    -w 判断对象是否存在,并且可写
    -x 判断对象是否存在,并且可执行
    -O 判断对象是否存在,并且属于当前用户
    -G 判断对象是否存在,并且属于当前用户组
    -nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ]
    -ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ]
    kaka 7年前 (2019年09月25日)
  4. #0

    矿泉水瓶高高

    181***[email protected]

    57

    除非你清楚自己在干什么,否则请避免在"Shell test命令"中使用单引号——使用它可能会导致难以察觉的错误,尤其是对于Shell初学者。

    让我用下列实例更进一步地解释为什么:

    #! /bin/bash
    # 模拟终端某一指令输出为空时用 test -z 配合单引号进行判断的效果 
    wrong=``
    #注意:反引号内没有任何字符
    echo $wrong
    if test -z '$wrong'; then
     echo "The result is empty."
    else
     echo "The result is not empty."
    fi
    

    执行一下:

    $ ./script-name.sh
    The result is not empty.

    执行后的结果与我们所期望的正好相反。这是因为单引号会将其内部的内容原样输出。

    此时不论命令的输出是否非空,最终都会被判为非空。

    而如果你此时没有察觉到错误的根源是单引号,相信我:你会想方设法去掉脚本输出的空格——而空格根本既无法消除又没有实际作用。

    矿泉水瓶高高

    181***[email protected]

    6年前 (2020年07月01日)
  5. #0

    kkk

    198***[email protected]

    32
    if [ -d "/data/" ];then
     echo "文件夹存在"
     else
     echo "文件夹不存在"
    fi

    "/data/" 双引号可以去掉。

    [] 内部两端要有空格、-d 参数和其他内容之间要有空格, 如果 then 另起一行的话 then 前不需要加 ; 否则需要在 then 前加 ;

    if test -d /data/
    then
     echo '文件夹存在!'
    else
     echo '文件夹不存在!'
    fi

    -d 参数和其他内容之间要有空格。

    then 要另起一行。

    kkk

    198***[email protected]

    6年前 (2020年08月17日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /