在 shell 脚本中,[
和 [[
都用于条件判断,但它们有一些重要的区别。
首先说一下 if 判断条件的语法:
基本语法
if condition; then
# 条件为真时执行的命令
elif another_condition; then
# 另一个条件为真时执行的命令
else
# 所有条件都为假时执行的命令
fi
字符串比较
条件 | 描述 |
---|---|
[[ $str1 == $str2 ]] | 检查两个字符串是否相等 |
[[ $str1 != $str2 ]] | 检查两个字符串是否不相等 |
[[ -z $str ]] | 检查字符串是否为空 |
[[ -n $str ]] | 检查字符串是否非空 |
示例
if [[ $USER == "root" ]]; then
echo "You are the root user."
else
echo "You are not the root user."
fi
if [[ -z $var ]]; then
echo "Variable is empty."
else
echo "Variable is not empty."
fi
数值比较
条件 | 描述 |
---|---|
[[ $num1 -eq $num2 ]] | 检查两个数值是否相等 |
[[ $num1 -ne $num2 ]] | 检查两个数值是否不相等 |
[[ $num1 -lt $num2 ]] | 检查 $num1 是否小于 $num2 |
[[ $num1 -le $num2 ]] | 检查 $num1 是否小于等于 $num2 |
[[ $num1 -gt $num2 ]] | 检查 $num1 是否大于 $num2 |
[[ $num1 -ge $num2 ]] | 检查 $num1 是否大于等于 $num2 |
示例
read -p "Enter a number: " num
if [[ $num -gt 10 ]]; then
echo "The number is greater than 10."
elif [[ $num -eq 10 ]]; then
echo "The number is equal to 10."
else
echo "The number is less than 10."
fi
文件测试
条件 | 描述 |
---|---|
[[ -e file ]] | 检查文件是否存在 |
[[ -f file ]] | 检查文件是否存在且为普通文件 |
[[ -d file ]] | 检查文件是否存在且为目录 |
[[ -r file ]] | 检查文件是否存在且可读 |
[[ -w file ]] | 检查文件是否存在且可写 |
[[ -x file ]] | 检查文件是否存在且可执行 |
示例
if [[ -e /etc/passwd ]]; then
echo "/etc/passwd exists."
else
echo "/etc/passwd does not exist."
fi
if [[ -f /etc/passwd ]]; then
echo "/etc/passwd is a regular file."
fi
正则表达式匹配
条件 | 描述 |
---|---|
[[ $str =~ regex ]] | 检查字符串是否匹配正则表达式 |
示例
IP=$(hostname -I)
if [[ $IP =~ ^10\.15\.80\.132$ ]]; then
echo "IP matches 10.15.80.132"
else
echo "IP does not match 10.15.80.132"
fi
# 匹配多个 IP 地址
if [[ $IP =~ ^10\.15\.80\.132$ || $IP =~ ^10\.0\.98\.50$ ]]; then
echo "IP matches either 10.15.80.132 or 10.0.98.50"
else
echo "IP does not match either 10.15.80.132 or 10.0.98.50"
fi
注意事项:
- 双括号
[[ ]]
:推荐使用双括号[[ ]]
而不是单括号[ ]
,因为双括号提供了更多的功能和更好的错误处理。- 空格:在条件表达式中,关键字和括号之间必须有空格。
- 转义字符:在正则表达式中,某些字符需要转义,如
.
和*
。
常见的疑问
1. 条件判断中的单个括号 [ ]
和 [[ ]]
有什么区别呢?
[
(test 命令)
- 语法:
[ condition ]
- 功能:这是一个传统的条件测试命令,相当于
test
命令。 - 特性:
- 需要在条件的两端加上空格,例如
[ "$var" -eq 0 ]
。 - 不支持逻辑运算符
&&
和||
,需要使用-a
和-o
代替。 - 支持的比较操作符有限,例如
-eq
,-ne
,-lt
,-le
,-gt
,-ge
等。 - 对于字符串比较,使用
=
和!=
。 - 需要特别注意转义字符和引号的使用,以避免语法错误。
- 需要在条件的两端加上空格,例如
[[
(扩展测试命令)
- 语法:
[[ condition ]]
- 功能:这是一个更现代和强大的条件测试命令。
- 特性:
- 不需要在条件的两端加上空格,例如
[[ $var -eq 0 ]]
。 - 支持逻辑运算符
&&
和||
。 - 支持更多的比较操作符,例如
=~
用于正则表达式匹配。 - 对于字符串比较,使用
==
和!=
。 - 更好的字符串处理能力,不需要对大多数特殊字符进行转义。
- 支持模式匹配,例如
[[ $string == pattern* ]]
。
- 不需要在条件的两端加上空格,例如
示例对比
使用 [
var=10
if [ "$var" -eq 10 ]; then
echo "var is 10"
fi
string="hello"
if [ "$string" = "hello" ]; then
echo "string is hello"
fi
使用 [[
var=10
if [[ $var -eq 10 ]]; then
echo "var is 10"
fi
string="hello"
if [[ $string == "hello" ]]; then
echo "string is hello"
fi
# 使用逻辑运算符
if [[ $var -eq 10 && $string == "hello" ]]; then
echo "Both conditions are true"
fi
# 使用正则表达式
if [[ $string =~ ^h[a-z]+$ ]]; then
echo "string matches the regex"
fi
[
是传统的条件测试命令,功能有限,但兼容性好。[[
是扩展的条件测试命令,功能强大,语法更灵活,推荐在现代 shell 脚本中使用。