shell/shell-括号.md

226 lines
8.0 KiB
Markdown
Raw Permalink Normal View History

2025-03-28 20:10:14 +08:00
<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 在 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
```