介绍
Shell 分 Bash / sh,字符串比较用 test 命令([ ] 是 test 的简写),[[ ]] 是 bash 增强版,推荐优先用 [[ ]],语法更安全,不用处理引号、空格问题。
[ ] 和 [[ ]] 区别
[ ]:POSIX 标准,兼容 sh/dash,不支持正则、不支持通配匹配,变量必须双引号,语法严格。[[ ]]:bash 扩展,语法容错强,自动处理空格,支持==通配、=~正则,推荐写bash脚本优先用。
基础语法
写法1:test 原生,POSIX 标准,所有shell都支持
test "str1" = "str2"
[ "str1" = "str2" ]
写法2:bash 增强双中括号(推荐)
注意:仅bash可用
[[ "str1" == "str2" ]]
坑
[ ]里面两边必须留空格,["a"="b"]直接报错=两边也要空格:[ "a"="b" ]错误;[ "a" = "b" ]正确- 变量一定要加双引号
[ "$var" = "abc" ],防止变量为空/带空格时语法崩溃 ==在[ ]里不是等于,只是 POSIX test 的字符串字面量,[ ]比较相等只用=;[[ ]]才支持==
字符串比较运算符
| 运算符 | 含义 | 适用 |
|---|---|---|
str1 = str2 |
字符串相等(完全一样) | [ ] / [[ ]] |
str1 != str2 |
字符串不相等 | [ ] / [[ ]] |
-z str |
字符串长度为0(空字符串) | [ ] / [[ ]] |
-n str |
字符串长度不为0(非空) | [ ] / [[ ]] |
str1 == pattern |
模式匹配(支持通配符 *, ?) |
仅 [[ ]] |
str1 =~ regex |
正则表达式匹配 | 仅 [[ ]] bash 3.0+ |
注意:
Shell 没有
><直接比较字符串大小,[ "a" > "b" ]会被当成重定向!字符串字典序比较:
[[ "apple" > "banana" ]](仅双中括号可用)
例子
1. 判断相等 / 不等
#!/bin/bash
name="linux"
# 相等判断
if [[ "$name" == "linux" ]]; then
echo "字符串相等"
fi
# 不相等
if [[ "$name" != "windows" ]]; then
echo "字符串不相等"
fi
2. 判断空字符串 -z -n
var=""
# -z 为空
if [[ -z "$var" ]]; then
echo "var 是空字符串"
fi
var="hello"
# -n 非空
if [[ -n "$var" ]]; then
echo "var 不为空"
fi
坑:var=" " 带空格不是空!-z 判断的是字符长度,空格也算字符。
3. [[ ]] 通配符模式匹配(* ?)
str="hello123"
# 以 hello 开头
if [[ "$str" == hello* ]]; then
echo "以hello开头"
fi
# 第二个字符是 e
if [[ "$str" == h?llo* ]]; then
echo "匹配通配符"
fi
解释:通配符模式不要加引号,加引号会当成普通字符串而不是模式。
4. [[ ]] 正则匹配 =~
str="abc123"
# 判断是否包含数字
if [[ "$str" =~ [0-9] ]]; then
echo "字符串包含数字"
fi
注意:正则不要加引号,引号会把正则表达式当成普通文本。
5. 字典序比较(字母先后)
# 比较字典序,a < b
if [[ "apple" < "banana" ]]; then
echo "apple 在字母顺序上小于 banana"
fi
坑总结
- ❌
[ $a = "abc" ]:变量没引号,$a为空会变成[ = "abc" ]语法报错
✅[ "$a" = "abc" ] - ❌
["a"="b"]:缺少空格
✅[ "a" = "b" ] - ❌
[ "$s" == "123" ]:POSIX[ ]规范里相等用=,虽然bash很多版本兼容==,不推荐 - ❌
[ $str =~ [0-9] ]:[ ]不支持正则 =~ - ❌
[[ "$str" == "hello*" ]]:模式加引号,*失去通配作用,变成字面星号 - ❌
[ "a" > "b" ]:单中括号里>被识别为文件重定向,会创建文件b!
多条件组合
在 [[ ]] 中:
&&逻辑与||逻辑或str="test123" if [[ -n "$str" && "$str" == test* ]]; then echo "非空,并且以test开头" fi