# PowerShell 使用注意事项

> 适用于 Windows 环境下的 Shell 命令执行。以下坑点均来自实际踩坑记录。

---

## 1. 没有 `head` / `tail` / `sed` / `awk`

PowerShell 不是 bash，这些 Unix 工具不存在。

| bash | PowerShell 替代 |
|------|-----------------|
| `cmd \| head -n 5` | `cmd \| Select-Object -First 5` |
| `cmd \| tail -n 3` | `cmd \| Select-Object -Last 3` |
| `grep pattern file` | `Select-String pattern file`（或直接调用 `rg`） |

**优先用 ripgrep (`rg`)**：搜索文件内容时直接用 `rg`，不依赖 PowerShell 内置工具。

---

## 2. 引号嵌套规则严格

PowerShell 对外部命令的引号处理不同于 bash：

- `"` 是双引号字符串，内部变量会展开
- `'` 是单引号字符串，不展开变量
- `-c "..."` 里再嵌套 Python 的 `"..."` 或 `r'...'` 时，层数超过两层极易出错

**示例：**

```powershell
# 危险：$e 会被 PowerShell 当作变量展开
python -c "print(f'error: {$e}')"

# 安全：用单引号包裹整个 -c 参数（PowerShell 不展开单引号）
python -c 'print("hello")'
```

**最佳实践**：复杂命令写进临时 `.py` 脚本文件执行，而不是用 `-c` 一行塞完。

---

## 3. `$` 变量展开干扰

在双引号字符串中，PowerShell 会尝试解析 `$var`、`${expr}`。如果 Python 代码里包含 f-string 的 `{...}` 或正则里的 `$`，会被 PowerShell 提前处理。

**应对**：用单引号包裹整个命令参数，或将逻辑写进脚本文件。

---

## 4. Unicode / GBK 编码冲突

Windows PowerShell 默认控制台编码是 GBK。当 Python 输出包含非 GBK 字符（如全角符号、emoji、CJK 扩展字符）时：

```
UnicodeEncodeError: 'gbk' codec can't encode character '\uff08' in position X
```

**解决：**

- Python 脚本开头加 `sys.stdout.reconfigure(encoding='utf-8')`
- 或设置环境变量 `$env:PYTHONIOENCODING = 'utf-8'`
- 或将输出写入文件而非直接打印到控制台

---

## 5. stderr 重定向行为不一致

bash 的 `2>&1` 在 PowerShell 中对外部程序（如 Python）有时能工作，但格式可能错乱。PowerShell 默认只捕获 stdout（流编号 6），stderr（流编号 2）需要显式合并。

| 写法 | 说明 |
|------|------|
| `cmd 2>&1` | stderr 合并到 stdout，对外部程序可用但不稳定 |
| `cmd *>&1` | PowerShell 特有语法，捕获所有输出流，更可靠 |

**实际表现**：Python Traceback 走 stderr，用 `2>&1` 有时被 PowerShell 拦截后格式错乱。建议优先写脚本文件执行。

---

## 6. 中文路径在错误回显中乱码

命令失败时，PowerShell 的 stderr 回显中包含中文的路径会显示为 `�����`。不影响命令执行本身，但会让错误信息难以阅读。

**应对**：优先通过 Python 脚本自身打印结构化错误（写入文件或返回 JSON），而非依赖 PowerShell 的错误捕获来诊断问题。

---

## 7. 管道传递的是对象而非文本

PowerShell 的管道传递的是 .NET 对象而非文本字节流。当把 PowerShell 管道接到外部程序时，对象的 `ToString()` 可能不是预期的格式。

---

## 核心原则速查

1. **复杂命令写脚本**：超过一行的操作，写成 `.py` 或 `.ps1` 文件执行
2. **优先用 ripgrep (`rg`)**：搜索文件内容时直接用 `rg`
3. **编码问题提前处理**：Python 入口设 `sys.stdout.reconfigure(encoding='utf-8')`
4. **避免 `-c` 嵌套引号超过两层**

---

*创建于 2026-05-27 | Windows PowerShell + Python 环境*