8.0 KiB
8.0 KiB
Shell 括号
一:括号介绍
1. 圆括号
特性 | () | (()) |
---|---|---|
用途 | 子 Shell 执行、命令替换、数组定义 | 整数算术运算、循环条件 |
执行环境 | 在子 Shell 中运行,不共享当前变量 | 在当前 Shell 中执行算术操作 |
变量影响 | 子 Shell 内变量修改不影响父 Shell | 直接修改当前 Shell 的变量 |
示例 | (a=1; echo $a) (退出后 a 恢复原值) |
((a=5+3)) (直接赋值给 a ) |
逻辑运算 | 不适用 | 支持 && , ` |
返回值 | 返回子 Shell 中最后一条命令的退出码 | 返回算术表达式是否为真(0为真,非0为假) |
2. 方括号
特性 | [ ] (test 命令) |
[[ ]] (Bash 增强条件) |
---|---|---|
兼容性 | POSIX 标准,所有 Shell 支持 | Bash/Ksh/Zsh 特有,非 POSIX |
字符串比较 | 用 = 或 != ,需严格转义空格 |
直接支持 == 、!= ,无需转义 |
模式匹配 | 不支持通配符(需用 case ) |
支持通配符(如 [[ $file == *.txt ]] ) |
正则匹配 | 不支持 | 支持 =~ (如 [[ "abc" =~ ^a ]] ) |
逻辑运算符 | 必须用 -a (AND)、-o (OR) |
直接使用 && 、` |
变量处理 | 变量未加引号可能导致语法错误 | 自动处理变量中的空格和特殊字符 |
数值比较 | 用 -eq 、-lt 等 |
也可用 -eq ,但推荐 (( )) |
示例 | [ "$a" -eq 5 -a "$b" != "" ] |
[[ $str == "yes" && $num > 10 ]] |
3. 花括号
特性 | 用途 | 示例 |
---|---|---|
代码块 | 组合命令(当前 Shell 执行) | { cmd1; cmd2; } > log.txt |
序列生成 | 生成数字/字母序列 | echo {1..5} → 1 2 3 4 5 |
文件名扩展 | 快速枚举文件或路径 | cp file.{txt,bak} → cp file.txt file.bak |
变量操作 | 字符串处理、默认值替换等 | ${var:-default} (空值时替换) |
注意 | 代码块首尾必须有空格和分号 | { echo "Start"; ls; } |
4. 总对比
括号类型 | 核心用途 | 关键区别 | 示例 |
---|---|---|---|
() |
子 Shell、数组、命令替换 | 子 Shell 中运行,不共享变量 | (cd /tmp; ls) |
(( )) |
整数算术运算、循环条件 | 直接操作变量,支持 C 风格语法 | for ((i=0; i<10; i++)) |
[ ] |
基础条件测试(兼容 POSIX) | 严格空格,需转义符号 | [ -f file ] |
[[ ]] |
增强条件测试(Bash 特有) | 支持通配符、正则、逻辑运算符 | [[ $str =~ ^[0-9]+$ ]] |
{} |
代码块、序列生成、变量扩展 | 不创建子 Shell,直接扩展内容 | echo {A..C} → A B C |
5. 常见误区
- 空格要求:
[ ]
和[[ ]]
内部必须保留空格:[ "$a" = 5 ]
✔️,[$a=5]
❌。(( ))
和[[ ]]
中的变量无需$
符号:((a++))
✔️,(($a++))
❌。
- 字符串比较:
[ ]
中必须用引号包裹变量,避免空值错误:[ "$str" = "hello" ]
。[[ ]]
中可不加引号(自动处理):[[ $str == hello ]]
。
- 数值比较:
[ ]
必须用-eq
、-lt
等操作符:[ $a -gt 10 ]
。[[ ]]
和(( ))
中可直接用>
、<
:[[ $a > 10 ]]
或((a > 10))
。
- 逻辑运算符:
[ ]
中用-a
(AND)、-o
(OR):[ $a -eq 1 -o $b -eq 2 ]
。[[ ]]
中用&&
、||
:[[ $a == 1 && $b == 2 ]]
。
二:示例
1. 圆括号
用途
- 子 Shell 执行:在独立环境中运行命令,不影响当前 Shell。
- 令替换:捕获命令输出。
- 数组定义:初始化数组。
示例:
# 子 Shell 示例:临时切换目录,不影响当前 Shell
[root@wxin ~]# (current_dir=$(pwd); cd /tmp; ls; cd "$current_dir")
# 命令替换:获取当前日期
[root@wxin ~]# today=$(date +"%Y-%m-%d")
[root@wxin ~]# echo "今天是$today"
今天是2025-03-26
# 数组定义
[root@wxin ~]# fruits=("apple" "banana" "cherry")
[root@wxin ~]# echo "第二个水果是 ${fruits[1]}"
第二个水果是 banana
2. 双括号
用途
- 整数算术运算:替代
expr
,支持 C 语言风格语法。 - 循环条件:简化
for
/while
循环。
示例:
# 算术运算
[root@wxin ~]# (( sum = 3+5*2 ))
[root@wxin ~]# echo "结果是 $sum"
结果是 13
# 自增操作
[root@wxin ~]# count=0
[root@wxin ~]# (( count++ ))
[root@wxin ~]# echo "计数: $count"
计数: 1
# 循环条件
[root@wxin ~]# for (( i=0;i<3;i++ ));do
> echo "循环第 $i 次"
> done
循环第 0 次
循环第 1 次
循环第 2 次
3. 方括号
用途
- 条件测试:兼容 POSIX 的基础条件判断。
- 文件检查:测试文件属性(如是否存在、是否可读)。
示例:
# 数值比较
[root@wxin ~]# if [ "$a" -eq 10 ];then echo "a 等于 10"; fi
a 等于 10
# 文件存在性检查
[root@wxin ~]# if [ -f "/etc/passwd" ];then
> echo "文件存在"
> fi
文件存在
# 逻辑组合(使用 -a/-o)
[root@wxin ~]# if [ "$a" -gt 5 -a "$a" -lt 15 ];then
> echo "a 在 5 到 15 之间"
> fi
a 在 5 到 15 之间
4. 双括号
用途
- 增强条件测试:支持通配符、正则表达式和逻辑运算符。
- 模式匹配:直接使用
==
或=~
。
示例:
# 字符串匹配(支持通配符)
[root@wxin ~]# file="image.jpg"
[root@wxin ~]# if [[ "$file" == *.jpg ]];then
> echo "这是一个 JPEG 文件"
> fi
这是一个 JPEG 文件
# 正则表达式匹配
[root@wxin ~]# phone="123-456-7890"
[root@wxin ~]# if [[ "$phone" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]];then
> echo "有效的电话号码"
> fi
有效的电话号码
# 逻辑运算符(直接使用 &&/||)
[root@wxin ~]# str="hello"
[root@wxin ~]# num=8
[root@wxin ~]# if [[ "$str" == "hello" && $num -gt 5 ]];then
> echo "条件满足"
> fi
条件满足
5. 花括号
用途
- 代码块:组合命令(当前 Shell 执行)。
- 序列生成:快速生成数字或字母序列。
- 文件名扩展:批量操作文件。
- 变量操作:字符串处理和默认值替换。
示例:
# 代码块(重定向所有输出)
[root@wxin ~]# {
> echo "操作开始于 $(date)"
> ls -l
> echo "操作结束"
> } > log.txt
# 序列生成
[root@wxin ~]# echo {1..5}
1 2 3 4 5
[root@wxin ~]# echo {A..C}
A B C
[root@wxin ~]# echo file{1..3}.txt
file1.txt file2.txt file3.txt
# 文件名扩展(快速复制备份)
[root@wxin ~]# cp config.txt{,.bak}
# 变量默认值替换
[root@wxin ~]# unset var
[root@wxin ~]# echo "${var:-默认值}"
默认值
# 字符串截取
[root@wxin ~]# filename="photo.jpg"
[root@wxin ~]# echo "${filename%.*}"
photo
[root@wxin ~]# echo "${filename##*.}"
jpg