正确使用 PowerShell 命令行

命令行不是一组需要死记硬背的“神秘指令”,而是一种直接、精确地向计算机表达操作意图的方式。图形界面适合探索,命令行则更适合重复操作、批量处理、故障排查和自动化。

这篇文章专门讨论我日常使用的 PowerShell,兼顾 Windows PowerShell 5.1 与跨平台的 PowerShell 7。目标不是收集尽可能多的命令,而是建立一套可靠的使用方法:理解对象管道,知道自己在哪里、命令将影响什么、如何预览结果,以及出错后如何判断问题所在。

本文中的示例默认在普通用户权限下执行。涉及删除、覆盖、管理员权限和网络密钥时,应先确认目标,再执行操作。

1 理解命令行环境

1.1 终端、Shell 和命令并不是一回事

  • 终端(Terminal):承载输入和输出的窗口,例如 Windows Terminal。
  • Shell:解释命令的程序,例如 PowerShell、Command Prompt、Bash 和 Zsh。
  • 命令:交给 Shell 执行的具体操作,例如 Get-ChildItemgit status
  • 进程(Process):命令运行后,由操作系统管理的程序实例。

同一终端里可以运行不同的 Shell,而同一个命令名在不同 Shell 中也可能有不同含义。因此,复制网上的命令前,首先要确认它是为 PowerShell、CMD 还是 Bash 编写的。

1.2 读懂命令提示符

PowerShell 常见的提示符如下:

PS C:\Users\name\Desktop\project>

其中:

  • PS 表示当前使用 PowerShell;
  • 中间的路径是当前工作目录;
  • > 后面才是准备输入命令的位置。

教程中的 PS C:\...>$# 通常只是提示符,不属于命令本身,不要一起复制。

1.3 命令的一般结构

命令 参数 选项

例如:

Get-ChildItem -Path .\_posts -Filter *.markdown

这里:

  • Get-ChildItem 是命令;
  • -Path-Filter 是具名参数;
  • .\_posts*.markdown 是参数值。

PowerShell 的命令通常采用“动词-名词”形式。可以用以下命令查看帮助:

Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Full

不确定命令是否存在时,可以先查询:

Get-Command git
Get-Command *Dns*

2 先确认自己在哪里

很多命令行事故并不是命令写错,而是在错误的目录中执行了正确的命令。

2.1 查看和切换目录

# 查看当前位置
Get-Location

# 查看当前目录内容
Get-ChildItem

# 包括隐藏文件
Get-ChildItem -Force

# 进入子目录
Set-Location .\cloudflare

# 返回上一级
Set-Location ..

pwdlscd 在 PowerShell 中通常也可用,但它们多为别名。在交互操作中使用别名很方便;写脚本和教程时,完整的 cmdlet 名称更清楚。

2.2 相对路径与绝对路径

  • . 表示当前目录;
  • .. 表示上一级目录;
  • .\assets\main.scss 是相对路径;
  • C:\Projects\blog\assets\main.scss 是绝对路径。

可以用下面两条命令在操作前确认目标:

Test-Path -LiteralPath '.\assets\main.scss'
Resolve-Path -LiteralPath '.\assets\main.scss'

-LiteralPath 会把路径按原样处理,不把其中的 *? 等字符解释为通配符。对移动、删除和重命名操作来说,它通常更安全。

2.3 路径中有空格时必须引用

Set-Location 'C:\Users\name\My Project'

单引号按字面值处理内容;双引号会展开变量:

$projectName = 'Viraha'
'项目是 $projectName'   # 不展开变量
"项目是 $projectName"   # 展开为:项目是 Viraha

3 文件和目录操作

3.1 查看与读取

# 查看文件列表
Get-ChildItem -File

# 递归查找 Markdown 文件
Get-ChildItem -Recurse -Filter *.markdown

# 读取整个文本文件
Get-Content -Raw -LiteralPath '.\README.md'

# 只查看前20行
Get-Content -LiteralPath '.\README.md' | Select-Object -First 20

若中文显示异常,明确指定编码通常有帮助:

Get-Content -Encoding utf8 -LiteralPath '.\README.md'

3.2 创建、复制和移动

# 创建目录
New-Item -ItemType Directory -Path '.\notes'

# 创建空文件
New-Item -ItemType File -Path '.\notes\draft.md'

# 复制文件
Copy-Item -LiteralPath '.\README.md' -Destination '.\notes\README-copy.md'

# 移动或重命名文件
Move-Item -LiteralPath '.\notes\draft.md' -Destination '.\notes\command-line.md'

执行覆盖操作前,可以先检查目标是否已经存在:

Test-Path -LiteralPath '.\notes\README-copy.md'

3.3 谨慎删除

先使用 -WhatIf 预览:

Remove-Item -LiteralPath '.\notes\command-line.md' -WhatIf

确认输出中的目标完全正确后,才考虑移除 -WhatIf。对递归删除尤其要谨慎:不要把工作区根目录、用户目录、未展开的变量或不确定的通配符作为删除目标。

一个稳妥的顺序是:

  1. Resolve-Path 获得绝对路径;
  2. Get-ChildItem 查看目标内容;
  3. 优先备份或移动到回收位置;
  4. -WhatIf 预览;
  5. 最后才执行实际删除。

4 通配符、筛选与搜索

4.1 通配符

  • * 匹配任意数量字符;
  • ? 匹配单个字符;
  • [0-9] 匹配指定范围内的一个字符。

例如:

Get-ChildItem -Filter '*.md'
Get-ChildItem -Filter '2026-*.markdown'

通配符很方便,但用于删除和移动时也容易扩大范围。先把同样的表达式交给 Get-ChildItem,确认匹配结果后再操作。

4.2 搜索文件内容

PowerShell 自带 Select-String

Get-ChildItem -Recurse -File |
  Select-String -Pattern 'TURNSTILE_HOSTNAME'

Git 仓库中可以使用:

git grep -n "guestbook_api"

如果安装了 ripgrep,则可以使用更快的 rg

rg -n "guestbook_api"
rg --files

工具不存在时,不要把“命令无法识别”误判为项目错误。先运行 Get-Command rg 检查是否安装,再选择 git grepSelect-String 替代。

5 管道、重定向与对象

5.1 PowerShell 管道传递的是对象

在 Bash 中,管道通常传递文本;PowerShell 管道主要传递带属性的对象。这使筛选和排序更可靠:

Get-ChildItem -File |
  Where-Object { $_.Length -gt 10KB } |
  Sort-Object Length -Descending |
  Select-Object Name, Length

其中 $_ 表示管道中当前处理的对象。

5.2 输出重定向

# 覆盖写入
Get-Date > .\time.txt

# 追加写入
Get-Date >> .\time.txt

# 将错误流写入文件
some-command 2> .\error.log

# 合并标准错误与标准输出
some-command *> .\all.log

使用 > 会覆盖原文件。保存重要输出时,先确认目标文件,或使用 >> 追加。

5.3 多条命令与成功条件

分号只表示“依次执行”,不保证前一条成功:

git add README.md; git commit -m "docs: update README"

如果第一条失败,第二条仍可能运行。PowerShell 7 支持 &&,但 Windows PowerShell 5.1 不支持。编写兼容脚本时,可以显式检查退出码:

git diff --check
if ($LASTEXITCODE -ne 0) {
  exit $LASTEXITCODE
}
git status

$LASTEXITCODE 主要记录原生程序(如 gitnode)的退出码;0 通常代表成功,非零值代表失败。

6 常用的系统与网络诊断

6.1 进程

# 查看进程
Get-Process

# 按名称筛选
Get-Process | Where-Object { $_.ProcessName -like '*ruby*' }

# 查看指定端口的连接
Get-NetTCPConnection -LocalPort 4000 -ErrorAction SilentlyContinue

结束进程会丢失该进程中尚未保存的工作。先确认进程 ID 和用途,再考虑使用 Stop-Process

6.2 DNS、端口与 HTTP

# 查询域名解析
Resolve-DnsName viraha.online -Type A

# 检查443端口
Test-NetConnection viraha.online -Port 443

# 查看 HTTP 响应头
curl.exe -I --max-time 20 "https://viraha.online"

在 Windows PowerShell 中,curl 可能是 Invoke-WebRequest 的别名。明确写成 curl.exe 可以确保调用真正的 curl 程序。

排查网络问题时应分层判断:

  1. DNS 能否解析域名;
  2. TCP 端口能否连接;
  3. TLS/HTTPS 是否成功;
  4. HTTP 状态码和响应正文是什么;
  5. 浏览器代理、扩展或缓存是否改变了网络路径。

命令行请求成功但浏览器失败时,应重点检查系统代理、VPN、Clash 规则、安全 DNS、浏览器扩展和缓存,而不是立刻修改服务器配置。

7 环境变量、权限与密钥

7.1 环境变量

PowerShell 中通过 $env: 访问环境变量:

$env:Path
$env:Path -split ';'

只为当前终端设置临时变量:

$env:APP_ENV = 'development'

关闭终端后,这个临时值通常会消失。

7.2 普通权限优先

不要习惯性地以管理员身份打开终端。普通权限足以完成大多数开发工作,也能限制错误命令的影响范围。只有在修改系统设置、安装系统级组件等确有需要时,才提升权限。

遇到 Permission denied 时,先检查:

  • 文件是否被其他程序占用;
  • 当前目录是否允许写入;
  • 文件是否只读;
  • 命令是否试图修改 .git、系统目录或其他受保护位置;
  • 是否真的需要管理员权限。

7.3 不要泄露密钥

API Token、Secret Key、密码和管理令牌不应:

  • 写进 Git 仓库;
  • 放进前端 JavaScript;
  • 截图公开;
  • 直接出现在可共享的命令历史或日志中。

应使用 GitHub Actions Secrets、Cloudflare Worker Secrets 或本机安全的环境变量。例如:

npx wrangler secret put TURNSTILE_SECRET_KEY

命令中只包含密钥名称,具体值由交互式提示输入。

8 用 Git 管理修改

命令行与 Git 配合时,最重要的是分清三个状态:工作区、暂存区和提交历史。

8.1 查看状态与差异

# 查看哪些文件发生变化
git status

# 查看尚未暂存的具体变化
git diff

# 查看已经暂存、准备提交的变化
git diff --staged

# 检查空格和行尾问题
git diff --check

git diff 进入分页器后,按 q 返回 PowerShell。

8.2 一个稳妥的提交顺序

git status
git diff
git add path/to/file
git diff --staged
git commit -m "docs: 完善命令行使用指南"
git push origin main

尽量明确列出需要暂存的文件,而不是习惯性使用 git add .。这样能避免把临时文件、密钥或无关修改一起提交。

8.3 更新本地仓库

在工作区干净时,可以使用:

git pull --ff-only origin main

--ff-only 只允许快进合并,遇到分叉时会停止,让使用者先了解情况,而不是自动产生意外的合并提交。

不要在不了解后果时使用:

git reset --hard
git clean -fd

它们可能直接丢弃本地工作。若确实需要重置,先备份或提交重要内容,并精确确认影响范围。

9 PowerShell 常用命令与别名

PowerShell 为交互使用提供了许多熟悉的别名,但别名并不等于另一套 Shell 的同名程序。例如,Windows PowerShell 中的 curl 可能指向 Invoke-WebRequest,并不一定是 curl 可执行文件。

目的 推荐的完整命令 常见别名
查看当前位置 Get-Location pwdgl
列出文件 Get-ChildItem lsdirgci
切换目录 Set-Location path cdsl
读取文件 Get-Content file cattypegc
复制文件 Copy-Item a b cpcopyci
移动文件 Move-Item a b mvmovemi
删除项目 Remove-Item path rmdelri
搜索文本 Select-String pattern file sls
查看进程 Get-Process psgps
排序对象 Sort-Object Property sort
筛选对象 Where-Object condition where?
遍历对象 ForEach-Object action %

交互操作时使用 cdls 等别名没有问题;写脚本、文档和自动化工作流时,完整 cmdlet 更容易阅读,也能减少跨环境歧义。可以用 Get-AliasGet-Alias ls 查询别名来源。

10 常见错误的排查方法

10.1 “不是 Git 仓库”

fatal: not a git repository

先运行:

Get-Location
Get-ChildItem -Force

确认当前目录或上级目录中是否存在 .git。不要因为这个错误就在任意目录执行 git init,否则可能制造嵌套仓库。

10.2 “无法识别为命令”

The term 'rg' is not recognized

可能原因包括:程序未安装、安装目录不在 PATH、命令名称拼错,或当前 Shell 不支持该语法。可以使用:

Get-Command rg -ErrorAction SilentlyContinue
$env:Path -split ';'

10.3 “找不到路径”

先确认当前位置和目标:

Get-Location
Test-Path -LiteralPath '.\目标路径'
Resolve-Path -LiteralPath '.\目标路径' -ErrorAction SilentlyContinue

常见原因是少进入或多进入了一层目录。

10.4 命令长时间无输出

不要立即重复执行。先判断命令是否可能正在等待:

  • 网络响应;
  • 密码或确认输入;
  • 文件锁;
  • 分页器;
  • 大量数据处理。

网络命令可以设置超时:

curl.exe --max-time 20 "https://example.com"

查看 git diff 时若停在分页页面,按 q 退出。

10.5 警告与错误要分开看

警告通常不会中止命令,例如依赖弃用或换行符提示;错误通常伴随非零退出码并阻止目标完成。阅读输出时优先寻找:

  • errorfatalfailed
  • HTTP 4xx/5xx 状态码;
  • exit code
  • 最先出现的真正错误,而不是后续连锁错误。

11 一套可靠的命令行工作流

面对陌生任务时,我更愿意遵循下面的顺序:

  1. 定位:用 Get-Location 确认当前位置;
  2. 观察:用 Get-ChildItemgit status 查看现状;
  3. 查询:用 Get-HelpGet-Command 确认命令行为;
  4. 缩小范围:明确具体文件、目录、分支或服务;
  5. 预览:使用 git diff-WhatIf 或只读命令确认影响;
  6. 执行一次:避免在结果未知时连续重复命令;
  7. 检查退出状态:观察错误信息和 $LASTEXITCODE
  8. 验证结果:重新运行只读检查,而不是仅凭“没有报错”判断成功;
  9. 记录与提交:把可复现的改动写进 Git,把密钥放进 Secret;
  10. 保留恢复路径:重要覆盖操作之前先备份。

一个简单的博客修改流程可以是:

Get-Location
git status
git diff
bundle exec jekyll build --strict_front_matter
git diff --check
git add _posts/目标文章.markdown
git diff --staged
git commit -m "docs: 更新文章"
git push origin main

12 动手练习

可以在一个临时练习目录中完成以下任务:

  1. 创建 command-line-practice 目录并进入;
  2. 创建 notes.txt
  3. 写入当前日期;
  4. 复制为 notes-backup.txt
  5. 列出目录中所有 .txt 文件;
  6. 搜索文件中的年份;
  7. 使用 -WhatIf 预览删除备份文件;
  8. 确认无误后再清理练习目录。

参考命令:

New-Item -ItemType Directory -Path '.\command-line-practice'
Set-Location '.\command-line-practice'
Get-Date | Set-Content -Encoding utf8 '.\notes.txt'
Copy-Item -LiteralPath '.\notes.txt' -Destination '.\notes-backup.txt'
Get-ChildItem -Filter '*.txt'
Select-String -Pattern '2026' -Path '.\*.txt'
Remove-Item -LiteralPath '.\notes-backup.txt' -WhatIf

练习的重点不是速度,而是每一步都能解释:当前目录是什么、命令将读取或修改哪个对象、如何确认结果,以及如何撤回。

结语

正确使用命令行,核心不是记住更多命令,而是形成稳定的判断习惯:先定位,后操作;先预览,后修改;先理解错误,再尝试修复;重要数据始终保留恢复路径。

当这些习惯成为本能后,命令行就不再是一块容易出错的黑色窗口,而会成为理解系统、复现流程和提高效率的可靠工具。

文章评论

欢迎围绕本文内容补充资料、分享经验或提出不同看法。请尽量保持友善并说明理由;评论经站长审核后公开。

  • 1填写表单
  • 2完成安全验证
  • 3审核后显示

发表评论

邮箱和真实姓名不会公开;真实姓名完全选填。评论只会显示在当前文章下,并需要审核后公开。

0 / 2000

提交后需站长审核通过才会显示

本文评论

  • 正在加载评论…