# Shell 学习对话总结

## 一、`cut` 命令

1. ** `-d` 指定分隔符**（默认 TAB），`-f` 选择字段（支持单字段、多字段、范围）。
    
2. ** `-f1` 和 `-f 1` 等价**，选项与参数间空格可选。
    
3. ** `cut` 不保留分隔符**：只按分隔符切割字段，输出时直接拼接字段值（不加分隔符）。GNU 版可用 `--output-delimiter` 自定义输出分隔符。
    
4. **无分隔符的行默认整行输出**，加 `-s` 可抑制。
    

---

## 二、Shell 脚本执行方式

|方式|是否需要 `x` 权限|执行环境|典型用途|
|---|---|---|---|
| `./hello.sh` |需要|子 Shell|独立运行脚本|
| `. ./hello.sh` 或 `source` |不需要|当前 Shell|加载变量/函数|
| `bash hello.sh` |不需要|子 Shell|指定解释器执行|

** `权限不够` 解决**：`chmod +x hello.sh`。

---

## 三、变量类型（三种）

|类型|定义方式|作用域|子进程可继承|
|---|---|---|---|
|私有变量| `var=value` |仅当前 Shell|❌|
|环境变量| `export var=value` |当前 Shell + 子进程|✔️|
|Shell 内建变量|Shell 预定义（`$BASH`, `$PS1`, `$?`）|全局，部分只读|部分|

**核心**：`export` 是变量能否被子进程继承的关键。

---

## 四、`PATH` 环境变量

1. **添加路径**：`export PATH="$PATH:/abs/path"`（必须绝对路径、必须加引号）。
    
2. **临时 vs 永久**：
    
    - 直接 `export` 仅当前 Shell 有效，退出失效。
        
    - 永久生效需写入 `~/.bashrc` 或 `~/.zshrc`，然后 `source`。
        
3. **省略 `./` 的原因**：`PATH` 中的目录会被 Shell 自动搜索，无需显式指定路径。
    

---

## 五、管道 vs 重定向

| 特性 | 管道 ` | ` | 重定向 `>` / `<` |  
|------|----------|----------------|  
| 数据流向 | 命令 → 命令 | 命令 ↔ 文件 |  
| 是否依赖文件 | ❌ | ✔️ |  
| 速度 | 快（内存） | 慢（磁盘 I/O） |  
| 典型场景 | 实时数据处理链 | 保存/读取持久化数据 |

---

## 六、`echo` 加引号问题

- **始终建议加双引号**：防止变量值含空格、通配符或特殊字符被 Shell 解析。
    
- **安全写法**：`echo "PATH=$PATH" >> .zshrc`。
    
- 更可靠替代：`printf "PATH=%s\n" "$PATH" >> .zshrc`。
    

---

## 七、Shell 计算

1. **交互式 Shell 可直接计算**，不限脚本。
    
2. **推荐语法**：
    
    bash
    
    ret=$((a + b))       # 算术
    ret=$((a < b))       # 比较，返回 1/0
    ret=$((a && b))      # 逻辑，返回 1/0
    ret=$((a & b))       # 按位，返回数值
    
1. ** `expr` 已过时**，语法晦涩需转义（`\<`, `\&`, `\|`），不推荐使用。
    
2. **浮点运算**需借助 `bc` 或 `awk`。
    

---

## 八、逻辑运算 vs 按位运算（重要）

|特性|逻辑与/或|按位与/或|
|---|---|---|
|操作对象|布尔值|二进制位|
|返回结果| `0` / `1` |数值|
|典型场景|条件判断|位掩码、权限控制|
|示例| `$((5 && 3))` → `1` | `$((0b101 & 0b110))` → `4` |

**关键**：`&&` / `||` 是逻辑，`&` / `|` 在 `$(( ))` 中是按位。

---

## 九、`expr` 的特殊性（避免使用）

1. ** `expr` 的 `|` **：模式匹配运算符，非逻辑或。规则：`ARG1` 非空非零返回 `ARG1`，否则返回 `ARG2`。
    
2. ** `expr` 的 `&` **：联合匹配运算符。规则：两者均非空非零返回 `ARG1`，否则返回 `0`。
    
3. ** `expr` 的比较符**（`\<`, `\>`, `\=`）：返回布尔值 `1` / `0`。
    
4. **不支持 `0b` 二进制**：会将 `0b101` 当字符串处理。
    
5. **结论**：`expr` 的所有功能均可用现代语法替代，**建议完全弃用**。
    

---

## 十、核心建议

1. **变量**：始终用双引号包裹（`"$var"`）。
    
2. **计算**：用 `$(( ))` 代替 `expr`。
    
3. **条件**：用 `[[ ]]` 或 `(( ))`。
    
4. **持久化**：写入 `~/.bashrc` 或 `~/.zshrc`。
    
5. **安全**：`PATH` 用绝对路径，避免 `.` 加入 `PATH`。


# 如何拥抱现代 Shell 语法，远离过时的 `expr`
> **`$(( ))` 做算术，`[[ ]]` 做判断，`${ }` 做字符串，`(( ))` 做条件。**

| 场景        | 语法                |
| --------- | ----------------- |
| 算术运算      | `$((...))`        |
| 条件判断（含正则） | `[[ ... ]]`       |
| 数值比较/逻辑   | `(( ... ))`       |
| 字符串操作     | `${var...}`       |
| 默认值/参数扩展  | `${var:-default}` |