在 Shell 脚本中,运算符是执行数学计算、逻辑判断、字符串操作和文件测试的核心工具。以下是 Shell 基本运算符的详细讲解,涵盖 算术运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符,并附有示例说明。
1. 算术运算符
用于执行数学运算(加减乘除、取模、赋值等)。Shell 本身不支持浮点数运算,但可以通过 bc
命令实现。
常用算术运算符
运算符 | 说明 | 示例代码 |
---|---|---|
+ | 加法 | a=$((10 + 5)) |
- | 减法 | a=$((10 - 5)) |
* | 乘法 | a=$((10 * 5)) |
/ | 除法 | a=$((10 / 3)) (结果为 3 ) |
% | 取余 | a=$((10 % 3)) (结果为 1 ) |
= | 赋值 | a=10 |
+= | 加后赋值 | a=10; a+=5 (等价于 a=15 ) |
-= | 减后赋值 | a=10; a-=5 (等价于 a=5 ) |
算术运算的实现方式
-
expr
命令(较老,需注意空格和转义):# 注意空格和乘号转义 val=$(expr 10 + 5) # 加法 val=$(expr 10 \* 5) # 乘法(* 需转义)
-
let
命令(直接操作变量,无需$
符号):let a=10+5 # a=15 let a*=2 # a=30(a = a * 2)
-
$(( ))
表达式(推荐方式,简洁高效):a=10 b=5 sum=$((a + b)) # sum=15 product=$((a * b)) # product=50
示例:计算表达式
#!/bin/bash
a=15
b=4
sum=$((a + b)) # 19
difference=$((a - b)) # 11
product=$((a * b)) # 60
quotient=$((a / b)) # 3(整数除法)
remainder=$((a % b)) # 3(取余)
echo "$a + $b = $sum"
echo "$a / $b (整除) = $quotient"
2. 关系运算符
用于比较两个数值的大小关系,仅支持数字比较。
常用关系运算符
运算符 | 说明 | 示例代码 |
---|---|---|
-eq | 等于 | [ 10 -eq 10 ] |
-ne | 不等于 | [ 10 -ne 20 ] |
-lt | 小于 | [ 5 -lt 10 ] |
-le | 小于等于 | [ 10 -le 10 ] |
-gt | 大于 | [ 20 -gt 10 ] |
-ge | 大于等于 | [ 10 -ge 5 ] |
示例:数值比较
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]; then
echo "$a 等于 $b"
else
echo "$a 不等于 $b"
fi
if [ $a -lt $b ]; then
echo "$a 小于 $b"
fi
3. 布尔运算符
用于组合多个条件,构建复杂的逻辑判断。
常用布尔运算符
运算符 | 说明 | 示例代码 |
---|---|---|
&& | 逻辑与 | [ $a -gt 5 ] && [ $a -lt 20 ] |
|| | 逻辑或 | [ $a -lt 5 ] || [ $a -gt 15 ] |
! | 逻辑非 | [ ! $a -eq 10 ] |
示例:布尔逻辑
#!/bin/bash
a=15
if [ $a -gt 10 ] && [ $a -lt 20 ]; then
echo "$a 在 10 到 20 之间"
fi
if [ $a -lt 5 ] || [ $a -gt 20 ]; then
echo "$a 不在 5 到 20 范围内"
else
echo "$a 在 5 到 20 范围内"
fi
4. 字符串运算符
用于字符串比较和操作。
常用字符串运算符
运算符 | 说明 | 示例代码 |
---|---|---|
= | 等于 | [ "$str1" = "$str2" ] |
!= | 不等于 | [ "$str1" != "$str2" ] |
-z | 字符串为空 | [ -z "$str" ] |
-n | 字符串非空 | [ -n "$str" ] |
示例:字符串操作
#!/bin/bash
str1="Hello"
str2="World"
str3=""
if [ "$str1" = "$str2" ]; then
echo "字符串相等"
else
echo "字符串不等"
fi
if [ -z "$str3" ]; then
echo "str3 是空字符串"
fi
5. 文件测试运算符
用于检查文件或目录的属性(是否存在、是否为文件、权限等)。
常用文件测试运算符
操作符 | 说明 |
---|---|
-b | 检测文件是否是块设备文件,如果是,则返回 true。 |
-c | 检测文件是否是字符设备文件,如果是,则返回 true。 |
-d | 检测文件是否是目录,如果是,则返回 true。 |
-f | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-g | 检测文件是否设置了 SGID 位,如果是,则返回 true。 |
-k | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 |
-p | 检测文件是否是有名管道,如果是,则返回 true。 |
-u | 检测文件是否设置了 SUID 位,如果是,则返回 true。 |
-r | 检测文件是否可读,如果是,则返回 true。 |
-w | 检测文件是否可写,如果是,则返回 true。 |
-x | 检测文件是否可执行,如果是,则返回 true。 |
-s | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e | 检测文件(包括目录)是否存在,如果是,则返回 true。 |
示例:文件检查
#!/bin/bash
file="example.txt"
if [ -e "$file" ]; then
echo "$file 存在"
if [ -f "$file" ]; then
echo "$file 是普通文件"
fi
else
echo "$file 不存在"
fi
6. 特殊运算符
-
命令替换(Command Substitution):执行命令并获取输出。
-
$(command)
会执行括号内的命令,并将命令的输出结果(标准输出)作为字符串替换到当前位置。示例:
# 获取当前目录路径 current_dir=$(pwd) echo "当前目录是: $current_dir"
-
动态参数传递
将命令的输出作为其他命令的参数。
示例:
# 列出当前目录下的文件 ls $(pwd)
等价于:
ls /home/user
-
嵌套命令替换
$()
支持嵌套使用,而反引号(`)在嵌套时容易混淆。示例:
# 获取某个目录下文件的数量 file_count=$(ls -1 $(pwd) | wc -l) echo "文件数量: $file_count"
-
与反引号(`)的区别
-
功能相同:$() 和反引号(
command
)都能实现命令替换。 -
推荐使用
$()
:- 可读性更好:$() 的结构更清晰,尤其是嵌套时。
- 避免混淆:反引号容易与单引号 ’ 混淆。
- 支持嵌套:反引号嵌套时需要转义,而 $() 更直观。
-
示例:
# 使用 $() 嵌套 result=$(echo "结果是: $(date)") echo "$result" # 使用反引号嵌套(需转义) result=`echo "结果是: \`date\`"` echo "$result"
-
-
-
变量引用(
${var}
):明确变量边界,避免歧义。name="John" echo "Hello, ${name}!" # 输出 Hello, John!
7. 注意事项
- 空格问题:Shell 运算符两侧必须有空格,例如
[ $a -eq $b ]
。 - 变量引用:使用
${var}
明确变量边界,例如echo "Value: ${var}X"
。 - 运算符选择:优先使用
$(( ))
进行整数运算,bc
处理浮点数。 - 转义字符:
expr
中的乘号*
需要转义为\*
。
总结
Shell 运算符是编写脚本时不可或缺的工具,掌握它们可以帮助你高效处理数学计算、逻辑判断、字符串操作和文件测试。推荐使用 $(( ))
进行整数运算,结合 [ ]
或 [[ ]]
进行条件判断,灵活运用布尔运算符和文件测试运算符,提升脚本的健壮性和功能性。
👍 千里之行,始于足下
😊 希望对你有帮助!