3.5 KiB
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'...'时,层数超过两层极易出错
示例:
# 危险:$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 回显中包含中文的路径会显示为 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>。不影响命令执行本身,但会让错误信息难以阅读。
应对:优先通过 Python 脚本自身打印结构化错误(写入文件或返回 JSON),而非依赖 PowerShell 的错误捕获来诊断问题。
7. 管道传递的是对象而非文本
PowerShell 的管道传递的是 .NET 对象而非文本字节流。当把 PowerShell 管道接到外部程序时,对象的 ToString() 可能不是预期的格式。
核心原则速查
- 复杂命令写脚本:超过一行的操作,写成
.py或.ps1文件执行 - 优先用 ripgrep (
rg):搜索文件内容时直接用rg - 编码问题提前处理:Python 入口设
sys.stdout.reconfigure(encoding='utf-8') - 避免
-c嵌套引号超过两层
创建于 2026-05-27 | Windows PowerShell + Python 环境