Linux Shell条件语句全面整理
一、基础测试命令
1. test 命令
test 表达式
test -f file.txt
test "abc" = "abc"
echo $?
2. [ ](单方括号)
[ 表达式 ]
[ $a -eq $b ]
a=10
b=20
if [ $a -lt $b ]; then
echo "a小于b"
fi
3. [[ ]](双方括号)
[[ 表达式 ]]
if [[ $str == "hello" ]]; then
echo "字符串匹配"
fi
4. (( ))(双括号)
(( 算术表达式 ))
a=5
b=10
if (( a < b )); then
echo "a小于b"
fi
二、详细用法对比
字符串比较
| 操作 |
test / [ ] |
[[ ]] |
说明 |
| 相等 |
"$a" = "$b" |
$a == $b |
[[ ]]中==是模式匹配 |
| 不等 |
"$a" != "$b" |
$a != $b |
|
| 为空 |
-z "$a" |
-z $a |
检查空字符串 |
| 非空 |
-n "$a" |
-n $a |
检查非空字符串 |
| 模式匹配 |
不支持 |
[[ $a == a* ]] |
支持通配符 |
| 正则匹配 |
不支持 |
[[ $a =~ ^a.* ]] |
支持正则表达式 |
数值比较
| 操作 |
test / [ ] |
(( )) |
[[ ]] |
说明 |
| 等于 |
$a -eq $b |
a == b |
a -eq b |
|
| 不等于 |
$a -ne $b |
a != b |
a -ne b |
|
| 小于 |
$a -lt $b |
a < b |
a -lt b |
|
| 小于等于 |
$a -le $b |
a <= b |
a -le b |
|
| 大于 |
$a -gt $b |
a > b |
a -gt b |
|
| 大于等于 |
$a -ge $b |
a >= b |
a -ge b |
|
文件测试
| 测试条件 |
说明 |
三种语法通用 |
-e file |
文件/目录是否存在 |
✓ |
-f file |
是否为普通文件 |
✓ |
-d file |
是否为目录 |
✓ |
-r file |
是否可读 |
✓ |
-w file |
是否可写 |
✓ |
-x file |
是否可执行 |
✓ |
-s file |
文件大小是否>0 |
✓ |
-L file |
是否为符号链接 |
✓ |
-O file |
是否属于当前用户 |
✓ |
逻辑运算符
| 运算符 |
test / [ ] |
[[ ]] |
(( )) |
说明 |
| 与 |
-a 或 &&(需转义) |
&& |
&& |
|
| 或 |
-o 或 ||(需转义) |
|| |
|| |
|
| 非 |
! |
! |
! |
|
| 分组 |
不支持 |
( ) |
( ) |
|
三、关键注意事项
[ ] 使用陷阱
[ "$a" = "$b" ]
["$a" = "$b"]
str="hello world"
[ -n $str ]
[ -n "$str" ]
[ "$a" = "$b" ]
[ "$a" = "yes" -a "$b" = "no" ]
[ "$a" = "yes" && "$b" = "no" ]
[[ ]] 优点和注意点
str="hello world"
[[ -n $str ]]
[[ $a == "yes" && $b == "no" ]]
[[ $file == *.txt ]]
[[ $name == [A-Z]* ]]
[[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]
[[ "$a" == "$b" ]]
(( )) 专用特性
(( a = 5 + 3 ))
(( a++ ))
(( result = a * b ))
a=5
b=10
(( a < b ))
(( a += 5 ))
(( a = b > 5 ? 10 : 20 ))
(( 0 ))
(( 1 ))
(( 5 > 3 ))
四、综合对比表
| 特性 |
test / [ ] |
[[ ]] |
(( )) |
| Shell支持 |
POSIX标准,所有shell |
bash、zsh等 |
bash、zsh等 |
| 变量引号 |
必须加引号 |
可不加引号 |
可不加引号 |
| 字符串比较 |
=或!= |
==、!=、模式匹配 |
不支持 |
| 数值比较 |
-eq、-ne等 |
-eq、-ne等或==、<等 |
==、!=、<、>等 |
| 模式匹配 |
不支持 |
支持(==、!=) |
不支持 |
| 正则表达式 |
不支持 |
支持(=~) |
不支持 |
| 逻辑运算符 |
-a、-o、! |
&&、||、! |
&&、||、! |
| 算术运算 |
不支持 |
有限支持 |
完整支持 |
| 安全性 |
容易出错(分词、路径扩展) |
安全(不分词、不扩展) |
安全 |
| 推荐使用场景 |
可移植脚本 |
bash脚本(优先使用) |
数值计算和比较 |
五、实用示例
组合使用示例
#!/bin/bash
file="test.txt"
count=5
name="example"
if [[ -f "$file" && -r "$file" ]] && (( count > 0 )); then
echo "文件存在、可读且count大于0"
if [[ $name =~ ^ex.* ]]; then
echo "名称以ex开头"
fi
fi
a=10
b=20
str="hello"
if (( a < b )) && [[ $str == "hello" ]]; then
echo "数值比较和字符串比较都通过"
fi
case $file in
*.txt) echo "文本文件" ;;
*.sh) echo "shell脚本" ;;
*) echo "其他文件" ;;
esac
最佳实践建议
- bash脚本中优先使用
[[ ]],更安全功能更全
- 需要可移植时使用
[ ],但要注意引号和空格
- 数值计算和比较使用
(( )),语法更直观
- 总是用引号包围
[ ]中的变量
- 复杂条件用
[[ ]]的&&、\|\|代替-a、-o
- 文件测试三种语法都可用,选择一致风格
常见错误避免
[ $var = "test" ]
[[ $var = "test" ]]
[ -f $file ]
[ -n "$var" ]
[ "$var" = "test" ]
[[ -f "$file" ]]
通过理解这些差异和最佳实践,可以编写更健壮、可读性更强的shell脚本。
所有评论(0)