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
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
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
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 ] # 或
[ "$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
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
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
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
常见错误与调试技巧
- 缺少空格:
[ "$a"="$b" ]
是错误的,正确是[ "$a" = "$b" ]
- 未引用的变量:
[ -f $file ]
应该为[ -f "$file" ]
- 混淆字符串和数值比较:使用
=
比较字符串,-eq
比较数值
调试技巧:在脚本开头添加 set -x
开启调试模式,或使用 echo
打印测试表达式:
实例
echo "测试表达式: [ $a -eq $b ]"
[ "$a" -eq "$b" ] && echo "成立" || echo "不成立"
[ "$a" -eq "$b" ] && echo "成立" || echo "不成立"
Balcon
you***err@163.com
符号含义:
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***err@163.com
开心小不点儿
swj***1@163.com
等同于:
开心小不点儿
swj***1@163.com
kaka
471***508@qq.com
参考地址
shell 判断文件夹或文件是否存在
文件夹不存在则创建
文件存在则删除
判断文件夹是否存在
判断文件是否存在
文件比较符
kaka
471***508@qq.com
参考地址
矿泉水瓶高高
181***9007@qq.com
除非你清楚自己在干什么,否则请避免在”Shell test命令“中使用单引号——使用它可能会导致难以察觉的错误,尤其是对于Shell初学者。
让我用下列实例更进一步地解释为什么:
执行一下:
执行后的结果与我们所期望的正好相反。这是因为单引号会将其内部的内容原样输出。
此时不论命令的输出是否非空,最终都会被判为非空。
而如果你此时没有察觉到错误的根源是单引号,相信我:你会想方设法去掉脚本输出的空格——而空格根本既无法消除又没有实际作用。
矿泉水瓶高高
181***9007@qq.com
kkk
198***2362@qq.com
"/data/" 双引号可以去掉。
[] 内部两端要有空格、-d 参数和其他内容之间要有空格, 如果 then 另起一行的话 then 前不需要加 ; 否则需要在 then 前加 ;。
-d 参数和其他内容之间要有空格。
then 要另起一行。
kkk
198***2362@qq.com