226 lines
8.0 KiB
Markdown
226 lines
8.0 KiB
Markdown
|
<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
|
|||
|
```
|
|||
|
|