在 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 脚本中使用。