Shell 的运算符种类不少,算术运算、比较运算、逻辑运算、文件测试各有各的语法。搞清楚这些,条件判断才能写对。
A=10
B=3
echo $((A + B)) # 加法:13
echo $((A - B)) # 减法:7
echo $((A * B)) # 乘法:30
echo $((A / B)) # 除法:3(取整)
echo $((A % B)) # 取余:1
echo $((A ** 2)) # 幂运算:100
自增自减:
N=5
((N++)) # N=6
((N--)) # N=5
((N+=3)) # N=8
((N-=2)) # N=6
复合赋值:
N=10
((N+=5)) # 等同于 N=N+5
((N*=2)) # 等同于 N=N*2
Shell 的比较运算符分两类:数字比较和字符串比较。这两套操作符不一样,容易混淆。
数字比较
用在 (( )) 或 [ ] 中:
A=10
B=20
# 在 (( )) 中用数学符号
if ((A < B)); then
echo "A 小于 B"
fi
# 在 [ ] 中用字母操作符
if [ $A -lt $B ]; then
echo "A 小于 B"
fi
数字比较操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
| -eq | 等于 | [ $A -eq $B ] |
| -ne | 不等于 | [ $A -ne $B ] |
| -gt | 大于 | [ $A -gt $B ] |
| -ge | 大于等于 | [ $A -ge $B ] |
| -lt | 小于 | [ $A -lt $B ] |
| -le | 小于等于 | [ $A -le $B ] |
字符串比较
STR1="hello"
STR2="world"
if [ $STR1 = $STR2 ]; then
echo "相等"
fi
if [ $STR1 != $STR2 ]; then
echo "不相等"
fi
字符串比较操作符:
| 操作符 | 含义 |
|---|---|
| = | 相等 |
| != | 不相等 |
| -z | 长度为零 |
| -n | 长度非零 |
# 判断字符串为空
if [ -z "$STR" ]; then
echo "字符串为空"
fi
# 判断字符串非空
if [ -n "$STR" ]; then
echo "字符串非空"
fi
在 [ ] 中
# 与
if [ $A -gt 0 -a $A -lt 10 ]; then
echo "A 在 0 到 10 之间"
fi
# 或
if [ $A -lt 0 -o $A -gt 10 ]; then
echo "A 不在 0 到 10 之间"
fi
# 非
if [ ! -f "$FILE" ]; then
echo "文件不存在"
fi
在 [[ ]] 中(推荐)
# 与
if [[ $A -gt 0 && $A -lt 10 ]]; then
echo "A 在 0 到 10 之间"
fi
# 或
if [[ $A -lt 0 || $A -gt 10 ]]; then
echo "A 不在 0 到 10 之间"
fi
# 非
if [[ ! -f $FILE ]]; then
echo "文件不存在"
fi
[[ ]] 比 [ ] 更强大,支持正则匹配,不需要转义:
# 正则匹配
if [[ $STR =~ ^[0-9]+$ ]]; then
echo "是数字"
fi
判断文件属性:
FILE="/etc/passwd"
if [ -e $FILE ]; then
echo "文件存在"
fi
if [ -f $FILE ]; then
echo "是普通文件"
fi
if [ -d $FILE ]; then
echo "是目录"
fi
常用文件测试操作符:
| 操作符 | 含义 |
|---|---|
| -e | 存在 |
| -f | 普通文件 |
| -d | 目录 |
| -r | 可读 |
| -w | 可写 |
| -x | 可执行 |
| -s | 非空(大小大于0) |
| -L | 符号链接 |
文件比较:
FILE1="a.txt"
FILE2="b.txt"
if [ $FILE1 -nt $FILE2 ]; then
echo "FILE1 比 FILE2 新"
fi
if [ $FILE1 -ot $FILE2 ]; then
echo "FILE1 比 FILE2 旧"
fi
A=5 # 二进制:101
B=3 # 二进制:011
echo $((A & B)) # 与:001 = 1
echo $((A | B)) # 或:111 = 7
echo $((A ^ B)) # 异或:110 = 6
echo $((~A)) # 取反
echo $((A << 2)) # 左移:10100 = 20
echo $((A >> 1)) # 右移:10 = 2
Shell 没有真正的三元运算符,但可以用 && 和 || 模拟:
A=10
B=20
# 类似 A > B ? "大" : "小"
[[ $A -gt $B ]] && echo "大" || echo "小"
注意这个技巧在 echo 前面的命令失败时可能出问题,复杂情况还是用 if。
运算符使用要点:
-eq、-lt 等,或用 (( ))=、!=[[ ]] 代替 [ ]-f、-d、-e 等$(( ))