shell/shell-括号.md
2025-03-28 20:10:14 +08:00

226 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<h2><center>Shell 括号</center></h2>
------
## 一:括号介绍
### 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 在 515 之间
```
### 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
```