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. 常见误区 1. 空格要求: - `[ ]` 和 `[[ ]]` 内部必须保留空格:`[ "$a" = 5 ]` ✔️,`[$a=5]` ❌。 - `(( ))` 和 `[[ ]]` 中的变量无需 `$` 符号:`((a++))` ✔️,`(($a++))` ❌。 2. 字符串比较: - `[ ]` 中必须用引号包裹变量,避免空值错误:`[ "$str" = "hello" ]`。 - `[[ ]]` 中可不加引号(自动处理):`[[ $str == hello ]]`。 3. 数值比较: - `[ ]` 必须用 `-eq`、`-lt` 等操作符:`[ $a -gt 10 ]`。 - `[[ ]]` 和 `(( ))` 中可直接用 `>`、`<`:`[[ $a > 10 ]]` 或 `((a > 10))`。 4. 逻辑运算符: - `[ ]` 中用 `-a`(AND)、`-o`(OR):`[ $a -eq 1 -o $b -eq 2 ]`。 - `[[ ]]` 中用 `&&`、`||`:`[[ $a == 1 && $b == 2 ]]`。 ## 二:示例 ### 1. 圆括号 **用途** - **子 Shell 执行**:在独立环境中运行命令,不影响当前 Shell。 - **令替换**:捕获命令输出。 - **数组定义**:初始化数组。 **示例:** ```bash # 子 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` 循环。 **示例:** ```bash # 算术运算 [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 的基础条件判断。 - **文件检查**:测试文件属性(如是否存在、是否可读)。 **示例:** ```bash # 数值比较 [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. 双括号 **用途** - **增强条件测试**:支持通配符、正则表达式和逻辑运算符。 - **模式匹配**:直接使用 `==` 或 `=~`。 **示例:** ```bash # 字符串匹配(支持通配符) [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 执行)。 - **序列生成**:快速生成数字或字母序列。 - **文件名扩展**:批量操作文件。 - **变量操作**:字符串处理和默认值替换。 **示例:** ```bash # 代码块(重定向所有输出) [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 ```