CMD、PowerShell 与 Bash 命令对照表

同一任务在命令提示符、PowerShell 和 bash 中的写法并排对照:文件、grep、环境变量、进程、网络、服务和脚本编写。

CMD vs PowerShell vs Bash · freetoolsforweb.com/tools/cmd-vs-powershell-vs-bash · 核实于 2026-10-18

最后核对:2026-10-18,依据 Microsoft Learn 上的 PowerShell 7.6 和 Windows PowerShell 5.1 参考、Windows 命令参考以及 GNU Bash 5.2 手册。

共 107 个任务,分为 9 组,另附别名、引号和执行策略说明

文件和文件夹

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
列出文件 #
PowerShell 别名:gci、dir,在 Windows 上还有 ls。
dir
Get-ChildItem
ls -l
列出文件(含隐藏文件) #
dir /a
Get-ChildItem -Force
ls -la
递归列出所有文件 #
dir /s /b
Get-ChildItem -Recurse -File
find . -type f
显示当前目录 #
在 CMD 中,不带参数的 cd 会输出当前目录。PowerShell 别名:pwd、gl;也可用 $PWD 变量。
cd
Get-Location
pwd
切换目录 #
CMD 需要加 /d 才能同时切换驱动器和文件夹。PowerShell 别名:cd、sl、chdir。
cd /d D:\work
Set-Location D:\work
cd /home/me/work
转到主目录 #
cd %USERPROFILE%
Set-Location ~
cd ~
创建文件夹(含父级) #
启用命令扩展时(默认启用),CMD 的 mkdir 会创建中间文件夹。在 PowerShell 中,mkdir 是封装了 New-Item -ItemType Directory 的函数。
mkdir a\b\c
New-Item -ItemType Directory -Path a\b\c
mkdir -p a/b/c
创建空文件 #
type nul > file.txt
New-Item file.txt
touch file.txt
复制文件 #
copy src.txt dst.txt
Copy-Item src.txt dst.txt
cp src.txt dst.txt
递归复制文件夹 #
xcopy src dst /E /I 也可以;robocopy 是官方支持的工具,可断点续传和重试。
robocopy src dst /E
Copy-Item src dst -Recurse
cp -r src dst
完全镜像文件夹 危险 #
危险: 两者都会删除目标中源里没有的文件。把两个路径写反会清空你本想保留的文件夹。robocopy /L 和 rsync -n 可以试运行。
robocopy src dst /MIR
(no cmdlet; call robocopy)
rsync -a --delete src/ dst/
移动文件 #
move a.txt archive\
Move-Item a.txt archive\
mv a.txt archive/
重命名文件 #
ren old.txt new.txt
Rename-Item old.txt new.txt
mv old.txt new.txt
删除文件 #
del file.txt
Remove-Item file.txt
rm file.txt
删除文件夹及其内容 危险 #
危险: 不经过回收站,使用 /q、-Force 或 -f 时也不会提示。请先检查路径;在 PowerShell 中加 -WhatIf 可查看将删除哪些内容。
rmdir /s /q folder
Remove-Item folder -Recurse -Force
rm -rf folder
更改文件权限 #
Windows 使用 ACL,而不是 rwx 权限位;icacls 通常比 Set-Acl 更简单。
icacls file.txt /grant alice:F
Get-Acl / Set-Acl
chmod 644 file.txt
文件校验和(SHA-256) #
Get-FileHash 默认使用 SHA256;其他算法用 -Algorithm MD5 或 SHA1。macOS:shasum -a 256。
certutil -hashfile file.iso SHA256
Get-FileHash file.iso
sha256sum file.iso
创建 zip 文件 #
Windows 10 1803 及更高版本自带 tar.exe(bsdtar);-a 会根据 .zip 扩展名选择格式。
tar -a -c -f out.zip folder
Compress-Archive -Path folder -DestinationPath out.zip
zip -r out.zip folder
解压 zip 文件 #
tar -xf out.zip
Expand-Archive out.zip -DestinationPath dest
unzip out.zip -d dest

读写文件内容

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
输出文件内容 #
PowerShell 别名:gc、type,在 Windows 上还有 cat。
type file.txt
Get-Content file.txt
cat file.txt
分页查看文件 #
more file.txt
Get-Content file.txt | Out-Host -Paging
less file.txt
最后 10 行 #无内置命令
Get-Content file.txt -Tail 10
tail -n 10 file.txt
实时跟踪日志文件 #无内置命令
Get-Content app.log -Tail 10 -Wait
tail -f app.log
将文本写入文件(覆盖) #
在 CMD 中,> 前面的空格会被写入文件。在 Windows PowerShell 5.1 中,> 写入 UTF-16 LE;PowerShell 7 写入不带 BOM 的 UTF-8。Set-Content -Encoding utf8 在两者中都能明确指定编码。
echo hello> file.txt
'hello' | Set-Content file.txt
echo hello > file.txt
向文件追加文本 #
echo hello>> file.txt
Add-Content file.txt 'hello'
echo hello >> file.txt
统计行数 #
find /c /v "" file.txt
(Get-Content file.txt).Count
wc -l file.txt
比较两个文件 #
在 Windows 上的 PowerShell 中,diff 是 Compare-Object 的别名,而不是文本比较。
fc a.txt b.txt
Compare-Object (Get-Content a.txt) (Get-Content b.txt)
diff a.txt b.txt
排序行 #
sort file.txt
Get-Content file.txt | Sort-Object
sort file.txt
去除重复行 #无内置命令
Get-Content file.txt | Sort-Object -Unique
sort -u file.txt
替换文件中的文本 #
-replace 使用正则表达式;括号会在 Set-Content 重新打开文件之前读完整个文件。macOS 的 sed 需要写 -i ''。
无内置命令
(Get-Content f.txt) -replace 'old','new' | Set-Content f.txt
sed -i 's/old/new/g' f.txt

环境变量

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
列出所有变量 #
set
Get-ChildItem Env:
env
读取变量 #
echo %PATH%
$env:PATH
echo "$PATH"
为当前会话设置 #
CMD:= 两边不能有空格,否则空格会成为名称和值的一部分。
set MY_VAR=hello
$env:MY_VAR = 'hello'
export MY_VAR=hello
永久设置(当前用户) #
setx 和 SetEnvironmentVariable 只对新窗口生效,对当前窗口无效。setx 会截断超过 1024 个字符的值,所以不要用它修改 PATH。
setx MY_VAR hello
[Environment]::SetEnvironmentVariable('MY_VAR','hello','User')
echo 'export MY_VAR=hello' >> ~/.bashrc
删除变量 #
set MY_VAR=
Remove-Item Env:MY_VAR
unset MY_VAR
将文件夹添加到 PATH(当前会话) #
Linux/macOS 上的 PowerShell 7 用 : 而不是 ; 分隔 PATH。[IO.Path]::PathSeparator 会给出正确的分隔符。
set PATH=%PATH%;C:\tools
$env:PATH += ';C:\tools'
export PATH="$PATH:/opt/tools"
仅对一条命令设置 #无内置命令
$env:DEBUG = '1'; ./app; Remove-Item Env:DEBUG
DEBUG=1 ./app

进程

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
列出进程 #
tasklist
Get-Process
ps aux
按名称查找进程 #
tasklist /FI "IMAGENAME eq chrome.exe"
Get-Process chrome
pgrep -a chrome
按进程 ID 结束进程 #
不加 /F 或 -Force 时,Windows 会请求进程自行关闭。kill 发送 SIGTERM;kill -9 强制结束。
taskkill /PID 1234 /F
Stop-Process -Id 1234 -Force
kill 1234
按名称结束进程 #
taskkill /IM notepad.exe /F
Stop-Process -Name notepad
pkill notepad
启动程序 #
start 中的空 "" 是窗口标题;没有它的话,带引号的程序路径会被当作标题。
start "" notepad.exe
Start-Process notepad
gedit &
以提升权限运行(管理员/root) #
Windows PowerShell 5.1 请用 powershell 代替 pwsh。Windows 11 24H2 及更高版本还可以在“设置”中启用内置的 sudo 命令。
runas /user:Administrator cmd
Start-Process pwsh -Verb RunAs
sudo command
CPU 占用前 10 的进程 #
Get-Process 中的 CPU 是启动以来累计的处理器秒数,而不是当前百分比。
无内置命令
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
ps aux --sort=-%cpu | head
查看占用端口的程序 #
Get-NetTCPConnection 仅限 Windows。netstat -ano 的最后一列是 PID:用 tasklist /FI "PID eq 1234" 查询。
netstat -ano | findstr :8080
Get-NetTCPConnection -LocalPort 8080
sudo ss -ltnp | grep :8080

网络

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
显示 IP 地址 #
Get-NetIPAddress 和其他 Net* cmdlet 仅限 Windows(NetTCPIP 模块)。
ipconfig /all
Get-NetIPAddress
ip addr
Ping 主机 #
Windows 的 ping 默认发送 4 次后停止;Linux 的 ping 会一直运行到按 Ctrl+C。
ping -n 4 example.com
Test-Connection example.com -Count 4
ping -c 4 example.com
测试 TCP 端口 #
Test-NetConnection 仅限 Windows。在 PowerShell 7 中:Test-Connection example.com -TcpPort 443。
无内置命令
Test-NetConnection example.com -Port 443
nc -zv example.com 443
DNS 查询 #
Resolve-DnsName 仅限 Windows;三者都有 nslookup。
nslookup example.com
Resolve-DnsName example.com
dig example.com
路由跟踪 #
tracert example.com
Test-NetConnection example.com -TraceRoute
traceroute example.com
清除 DNS 缓存 #
bash 这一行适用于使用 systemd-resolved 的系统。
ipconfig /flushdns
Clear-DnsClientCache
sudo resolvectl flush-caches
HTTP GET(API 调用) #
Invoke-RestMethod 会把 JSON 解析为对象;Invoke-WebRequest 返回状态码、标头和原始内容。
curl.exe https://api.example.com/items
Invoke-RestMethod https://api.example.com/items
curl https://api.example.com/items
下载文件 #
Windows 10 1803 及更高版本自带 curl.exe。在 Windows PowerShell 5.1 中,如果机器未设置 Internet Explorer,请为 Invoke-WebRequest 加上 -UseBasicParsing。
curl.exe -L -o file.zip https://example.com/file.zip
Invoke-WebRequest https://example.com/file.zip -OutFile file.zip
curl -LO https://example.com/file.zip
POST JSON #
CMD 没有单引号,所以 curl.exe 的内部双引号要用反斜杠转义。
curl.exe -X POST -H "Content-Type: application/json" -d "{\"a\":1}" https://api.example.com
Invoke-RestMethod https://api.example.com -Method Post -ContentType 'application/json' -Body (@{a=1} | ConvertTo-Json)
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://api.example.com
SSH 连接服务器 #
Windows 10 1809+ 和 Windows 11 默认已安装 OpenSSH 客户端。
ssh user@host
ssh user@host
ssh user@host

服务和系统

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
列出服务 #
在 Windows PowerShell 5.1 中,sc 是 Set-Content 的别名:请输入 sc.exe。PowerShell 6+ 已删除该别名。
sc query
Get-Service
systemctl list-units --type=service
服务状态 #
sc query Spooler
Get-Service Spooler
systemctl status nginx
启动 / 停止服务 #
net start Spooler net stop Spooler
Start-Service Spooler Stop-Service Spooler
sudo systemctl start nginx sudo systemctl stop nginx
重启服务 #
net stop Spooler && net start Spooler
Restart-Service Spooler
sudo systemctl restart nginx
开机自启 #
sc.exe 要求 start= 后面有空格,前面没有空格。
sc config Spooler start= auto
Set-Service Spooler -StartupType Automatic
sudo systemctl enable nginx
操作系统和硬件信息 #
systeminfo
Get-ComputerInfo
uname -a; cat /etc/os-release
计算机名 #
hostname
$env:COMPUTERNAME
hostname
当前用户 #
在 Windows 上的 PowerShell 中也可用 $env:USERNAME。
whoami
whoami
whoami
磁盘可用空间 #
较旧的 Windows 版本运行 fsutil 需要管理员提示符。Get-Volume(仅限 Windows)也会显示容量和可用空间。
fsutil volume diskfree C:
Get-PSDrive -PSProvider FileSystem
df -h
运行时间 #
Get-Uptime 需要 PowerShell 6+。在 5.1 中:(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime。
systeminfo | find "Boot Time"
Get-Uptime
uptime
立即重启 #
shutdown /r /t 0
Restart-Computer
sudo reboot
清屏 #
在 Windows 上的 PowerShell 中,cls 和 clear 都能用。
cls
Clear-Host
clear
命令历史 #
Get-History 只包含当前会话。PSReadLine 会把更早的历史保存在 (Get-PSReadLineOption).HistorySavePath 文件中;三个 Shell 都可以用 Ctrl+R 搜索历史。
doskey /history
Get-History
history
查看命令帮助 #
运行一次 Update-Help(5.1 中需管理员权限)即可下载完整的 PowerShell 帮助。
dir /?
Get-Help Get-ChildItem -Examples
man ls
当前日期 #
%date% 遵循本机的区域格式,因此解析它的脚本换个区域设置就会出错。
echo %date%
Get-Date -Format 'yyyy-MM-dd'
date +%F
等待 5 秒 #
timeout /t 5
Start-Sleep -Seconds 5
sleep 5
将输出复制到剪贴板 #
macOS:pbcopy。Wayland:wl-copy。在 PowerShell 中用 Get-Clipboard 读取。
dir | clip
Get-ChildItem -Name | Set-Clipboard
ls | xclip -selection clipboard

管道传递对象与文本

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
选取列 / 属性 #
PowerShell 的管道传递的是 .NET 对象,因此直接按名称选择属性,而不用解析列。
无内置命令
Get-Process | Select-Object Name, Id, WS
ps -eo comm,pid,rss
按值筛选行 #
PowerShell 能识别 500MB、1GB 这样的字面量。awk 比较的是第 6 列(RSS,单位 KB)。
tasklist | findstr chrome
Get-Process | Where-Object WS -gt 500MB
ps aux | awk '$6 > 500000'
对每一项执行操作 #
$_(或 $PSItem)表示当前对象。在 .bat 文件中要写 %%f 而不是 %f。
for %f in (*.txt) do echo %f
Get-ChildItem *.txt | ForEach-Object { $_.Name }
for f in *.txt; do echo "$f"; done
查看对象有哪些属性 #
PowerShell 中最有用的探索命令;也可试试 | Format-List *。
无内置命令
Get-Process | Get-Member
无内置命令
解析 JSON #
使用 -Raw 让文件作为一个字符串读入;输出时用 ConvertTo-Json -Depth 10(默认深度为 2)。
无内置命令
Get-Content data.json -Raw | ConvertFrom-Json
jq . data.json
读取并筛选 CSV #
Import-Csv 读取的值都是字符串;数值比较时要用 [int] 转换。
无内置命令
Import-Csv users.csv | Where-Object { [int]$_.Age -gt 30 }
awk -F, 'NR>1 && $3 > 30' users.csv
导出为 CSV #
-NoTypeInformation 在 PowerShell 6+ 中是默认行为,但在 5.1 中需要手动加上。
无内置命令
Get-Process | Export-Csv procs.csv -NoTypeInformation
ps -eo pid,comm --no-headers | awk '{print $1","$2}' > procs.csv
计数、求和、平均值 #
find /c /v "" file.txt
Get-ChildItem -File | Measure-Object Length -Sum -Average
ls -l | awk '{s+=$5} END {print s}'

脚本:变量、条件、循环、函数

任务CMD(命令提示符)PowerShellBash(Linux/macOS)
设置变量 #
bash:= 两边不能有空格(name = Ada 会运行一个名为 name 的命令)。
set name=Ada
$name = 'Ada'
name=Ada
在字符串中使用变量 #
echo Hello %name%
"Hello $name"
echo "Hello $name"
算术运算 #
CMD 和 bash 只能做整数运算;PowerShell 使用 .NET 数值类型。
set /a n=5*3
$n = 5 * 3
n=$((5 * 3))
读取用户输入 #
set /p name=Name:
$name = Read-Host 'Name'
read -rp 'Name: ' name
脚本参数 #
在 .bat 文件中,%~1 会去掉两边的引号。param() 块可为 PowerShell 脚本提供命名且带类型的参数。
%1 %2 … %*
$args[0] or param($Path)
$1 $2 … "$@"
字符串的 if / else #
PowerShell 的比较运算符是单词:-eq -ne -gt -lt -like -match。= 和 > 分别是赋值和重定向。
if "%a%"=="yes" (echo on) else (echo off)
if ($a -eq 'yes') { 'on' } else { 'off' }
if [ "$a" = "yes" ]; then echo on; else echo off; fi
比较数字 #
CMD:EQU NEQ LSS LEQ GTR GEQ。
if %n% GTR 5 echo big
if ($n -gt 5) { 'big' }
if (( n > 5 )); then echo big; fi
判断文件是否存在 #
if exist file.txt echo yes
if (Test-Path file.txt) { 'yes' }
if [ -f file.txt ]; then echo yes; fi
上一个程序的退出码 #
在 PowerShell 中,$? 表示上一条命令的 $true/$false;$LASTEXITCODE 是上一个原生程序的数字退出码。
echo %ERRORLEVEL%
$LASTEXITCODE
echo $?
仅在成功 / 失败时运行下一条命令 #
&& 和 || 管道链运算符是 PowerShell 7.0 才加入的;Windows PowerShell 5.1 不接受。
build && deploy build || echo failed
build && deploy (PowerShell 7+) build; if ($?) { deploy } (5.1)
build && deploy build || echo failed
遍历列表 #
for %i in (a b c) do echo %i
foreach ($x in 'a','b','c') { $x }
for x in a b c; do echo "$x"; done
从 1 循环到 5 #
for /l %i in (1,1,5) do echo %i
foreach ($i in 1..5) { $i }
for i in {1..5}; do echo "$i"; done
逐行遍历文件 #
for /f "usebackq delims=" %l in ("file.txt") do echo %l
foreach ($line in Get-Content file.txt) { $line }
while IFS= read -r line; do echo "$line"; done < file.txt
while 循环 #
CMD 没有 while;在 .bat 文件中用 goto 加标签实现。
:loop set /a i+=1 if %i% lss 5 goto loop
while ($i -lt 5) { $i++ }
while [ "$i" -lt 5 ]; do i=$((i+1)); done
定义并调用函数 #
像调用命令一样调用 PowerShell 函数:Greet Ada,而不是 Greet("Ada")。
call :greet Ada goto :eof :greet echo Hello %~1 exit /b
function Greet($Name) { "Hello $Name" } Greet Ada
greet() { echo "Hello $1"; } greet Ada
将命令输出存入变量 #
for /f "delims=" %i in ('hostname') do set h=%i
$h = hostname
h=$(hostname)
丢弃输出 #
command >nul 2>&1
command *> $null
command >/dev/null 2>&1
注释 #
rem comment :: comment
# comment <# block #>
# comment
脚本文件及其运行方式 #
PowerShell 不会运行当前文件夹中未加 .\ 的脚本,甚至可能完全阻止运行:参见下方的执行策略。
script.bat
.\script.ps1
chmod +x script.sh && ./script.sh

PowerShell 别名陷阱:ls、curl、wget、sc、where

PowerShell 自带一些看起来像 Unix 或 CMD 命令的别名,但实际运行的是参数不同的 cmdlet。具体有哪些别名取决于版本和操作系统。Get-Alias name 可显示某个名称在当前会话中指向什么。

你输入Windows PowerShell 5.1Windows 上的 PowerShell 7Linux/macOS 上的 PowerShell 7
curl
在 5.1 中输入 curl.exe 才能使用真正的 curl。它的参数(-X、-H、-d)对 Invoke-WebRequest 毫无意义。
Invoke-WebRequest不是别名:运行 curl.exe原生 curl
wget
使用 Invoke-WebRequest url -OutFile name,或 curl.exe -LO url。
Invoke-WebRequest不是别名(Windows 默认没有 wget)原生 wget(如已安装)
ls, dir
ls -la 这类参数在 Windows 上会出错:请用 Get-ChildItem -Force。
Get-ChildItemGet-ChildItemls = 原生 ls;dir = Get-ChildItem
cat, typeGet-ContentGet-Contentcat = 原生 cat;type = Get-Content
cp, mv, rm, rmdir
rm -rf 不是合法的 PowerShell 写法:请用 Remove-Item -Recurse -Force。
Copy-Item, Move-Item, Remove-Item相同的 cmdlet原生命令
ps, killGet-Process, Stop-Process相同的 cmdlet原生命令
sort, tee, diff
在 Windows 上的 PowerShell 中,diff a b 比较的是对象,而不是两个文件的各行。
Sort-Object, Tee-Object, Compare-Object相同的 cmdlet原生命令
sc
在 5.1 中,sc query 会写入一个名为 query 的文件。请使用 sc.exe。
Set-Content不是别名:运行 sc.exe不适用
where
使用 where.exe 或 Get-Command 查找程序。
Where-ObjectWhere-ObjectWhere-Object
echo
echo -n 不会去掉换行;请用 Write-Host -NoNewline。
Write-OutputWrite-OutputWrite-Output
manhelphelp原生 man

引号与转义

大多数“在一个 Shell 里能用、换一个就出错”的问题都出在引号上。每个 Shell 的转义字符都不一样。

项目CMDPowerShellBash
字面字符串(不展开变量)没有字面引号:即使在 "…" 中 %VAR% 也会展开'Cost: $5''Cost: $5'
含变量的字符串"Hello %name%""Hello $name, it is $(Get-Date -Format t)""Hello $name, it is $(date +%R)"
转义字符^(例如 ^& ^| ^>)` 反引号(例如 `n 换行、`t 制表符、`$ 字面 $)\ 反斜杠
引号字符串中的引号多数程序在 "…" 中用 "";因程序而异'It''s' 或 "Say `"hi`""'It'\''s' 或 "Say \"hi\""
续行行尾加 ^行尾加 `(或以 | 结束一行)行尾加 \
脚本中的字面 % 或 $.bat 文件中写 %%单引号中的 '$' 或 `$单引号中的 '$' 或 \$
将参数原样传给原生程序(不需要)--% 让 PowerShell 停止解析该行其余部分(不需要)

PowerShell 7.3 改变了向原生程序(curl.exe、git、node)传递引号的方式:带内嵌双引号的参数现在会按原样传递,由 $PSNativeCommandArgumentPassing 控制。在 Windows PowerShell 5.1 中,同样的 JSON 请求体通常需要对内部引号进行两次转义,这也是很多人改用 Invoke-RestMethod 搭配 ConvertTo-Json 的原因。

执行策略:“此系统上禁止运行脚本”

当执行策略为 Restricted 时,PowerShell 会拒绝运行 .ps1 文件;这是 Windows 客户端版本(Windows 10 和 11)上 Windows PowerShell 的实际默认值。Windows Server 默认为 RemoteSigned:本地脚本可以运行,下载的脚本必须签名或解除锁定。在 Linux 和 macOS 上,策略为 Unrestricted,且无法更改。

  • Get-ExecutionPolicy -List 显示各个作用域的策略;定义了策略的最具体作用域生效(组策略优先于所有作用域)。
  • Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 让你自己的脚本无需管理员权限即可运行。
  • Unblock-File .\script.ps1 清除你信任的脚本上的“从 Internet 下载”标记。
  • pwsh -ExecutionPolicy Bypass -File script.ps1(5.1 用 powershell)只对单个会话应用某个策略。

执行策略是防止误运行脚本的保险,而不是安全边界:任何人都可以把脚本内容粘贴到控制台中运行。

Windows PowerShell 5.1 与 PowerShell 7

  • 两个程序:powershell.exe 是 Windows PowerShell 5.1,内置于 Windows,不再增加新功能。pwsh 是 PowerShell 7,需单独安装,可跨平台,两者可以并存。
  • 7.0 新增的运算符:命令之间的 && 和 ||、三元运算符 $a ? 'yes' : 'no',以及空值合并运算符 ?? / ??=。
  • 文件编码:5.1 的 > 和 Out-File 写入 UTF-16 LE,Set-Content 使用 ANSI 代码页。PowerShell 7 一律写入不带 BOM 的 UTF-8,这正是 Git、Linux 工具和大多数编辑器所期望的。
  • 别名:7 在 Windows 上去掉了 curl、wget 和 sc,在 Linux/macOS 上则把 ls、cp、rm、cat、ps 等交给原生命令(见上表)。
  • 模块差异:Get-NetIPAddress、Test-NetConnection 和 Resolve-DnsName 等仅限 Windows 的 cmdlet 在 Windows 上的 PowerShell 7 中可用,但在 Linux 或 macOS 上不存在。

在 Windows 上运行 bash:WSL

适用于 Linux 的 Windows 子系统在 Windows 旁运行真正的 Linux 发行版,因此右侧一栏的所有 bash 命令都能照原样运行。在管理员提示符中运行 wsl --install 即可安装,默认发行版为 Ubuntu(Windows 10 版本 2004 及更高版本,以及 Windows 11);wsl -l -v 列出已安装的发行版。

  • 从 CMD 或 PowerShell 运行一条 Linux 命令:wsl ls -la,或跨系统使用管道:dir | wsl grep txt。
  • Windows 驱动器在 Linux 中位于 /mnt/c 下;在资源管理器中可通过 \\wsl.localhost\Ubuntu 访问 Linux 文件(旧版本:\\wsl$\Ubuntu)。
  • 请把项目放在 Linux 文件系统中(~/),而不是 /mnt/c:跨系统边界访问文件要慢得多。

想深入了解 Linux 这一侧,请参阅Linux 命令速查表。

静态参考资料,在浏览器中运行;你的搜索内容不会发送到任何地方。 浏览全部免费工具.

发现问题,或者觉得哪里可以更好?每条消息我们都会阅读,并尽快修复。

这份 CMD、PowerShell 与 Bash 对照表把同一任务在 Windows 命令提示符、PowerShell 和 bash 中的写法放在同一行:列出和复制文件、在文件中查找文本(PowerShell 中 grep 的对应命令是 Select-String)、环境变量、进程、网络、服务、读写文件内容,以及用变量、条件判断、循环和函数编写脚本。用三种 Shell 中任意一种的命令搜索,就能找到它在另外两种中的对应写法,每条都附有复制按钮。

速查表还涵盖了在几种 Shell 之间切换时常见的问题:看起来像 Unix 命令其实不是的 PowerShell 别名(Windows PowerShell 5.1 中的 curl 和 wget,Windows 上所有版本中的 ls 和 rm)、不同的引号和转义字符、阻止 .ps1 脚本运行的执行策略错误,以及 Windows PowerShell 5.1 与 PowerShell 7 的差异。除非另有说明,PowerShell 命令在两个版本中都适用;没有对应 CMD 命令的地方,表格会如实注明,而不会凭空编造。

使用方法

  1. 用你熟悉的任意 Shell 命令搜索(例如“grep”“findstr”或“Select-String”),或者按任务搜索(如“结束进程”“环境变量”)。
  2. 横向阅读该行,找到另外两种 Shell 中的对应命令,点击所需命令旁的“复制”。
  3. 查看任务名称下方的说明:它会标出版本差异(PowerShell 5.1 与 7)和仅限 Windows 的 cmdlet。
  4. 如果某条命令的行为与预期不同,请滚动到别名、引号和执行策略部分。
  5. 使用“打印 / 另存为 PDF”保存一份放在手边;本页在手机上也能使用,每行会变成一张卡片。

常见问题

PowerShell 中 grep 的对应命令是什么?

Select-String。搜索文件用 Select-String -Path app.log -Pattern error,筛选命令输出用 ipconfig | Select-String IPv4。它默认不区分大小写(加 -CaseSensitive 可区分),使用 .NET 正则表达式,-NotMatch 相当于 grep -v。要递归搜索,就把 Get-ChildItem -Recurse -Filter *.log 通过管道传给 Select-String。它的简短别名是 sls。

为什么 curl 在 PowerShell 中表现异常?

在 Windows PowerShell 5.1 中,curl 和 wget 是 Invoke-WebRequest 的别名,所以 -X、-H 和 -d 等 curl 参数会被拒绝或被解释为其他含义。输入 curl.exe 即可运行 Windows 10 1803 及更高版本自带的真正 curl。PowerShell 7 删除了这些别名,所以在那里 curl 运行的就是 curl.exe。在 Linux 和 macOS 上,curl 从来都不是别名。

PowerShell 比 CMD 好吗?

只要不是单纯运行一个程序或一个简短的批处理文件,答案都是肯定的。PowerShell 的管道传递的是结构化对象而不是文本,因此你可以按属性名筛选和排序(Where-Object、Sort-Object),而不必解析列;它还有真正的函数、错误处理、JSON 和 CSV 支持以及远程管理。CMD 依然适合旧的 .bat 文件和一些安装程序,而且所有 CMD 工具(ipconfig、robocopy、netstat)也都能在 PowerShell 中运行。

如何解决“running scripts is disabled on this system”(此系统上禁止运行脚本)?

这是执行策略导致的,Windows 10 和 11 客户端版本默认设为 Restricted。在 PowerShell 中运行 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser(无需管理员权限)。之后你自己的脚本就能运行,而从互联网下载的脚本必须经过签名,或用 Unblock-File 解除锁定。Get-ExecutionPolicy -List 会显示各作用域的设置;组策略设置会覆盖你自己的任何设置。

可以在 Windows 上运行 bash 命令吗?

可以,借助适用于 Linux 的 Windows 子系统(WSL)。在提升权限的命令行中运行 wsl --install(需要 Windows 10 版本 2004 或更高,或 Windows 11)来安装 Ubuntu,然后从开始菜单打开它,或在 CMD 或 PowerShell 中用 wsl 加命令运行单条命令,例如 wsl grep -rn TODO。Git for Windows 还附带 Git Bash,这是一个更轻量的 bash,包含常用的 Unix 工具。

Windows PowerShell 和 PowerShell 7 有什么区别?

Windows PowerShell 5.1(powershell.exe)内置于 Windows,只接收修复更新。PowerShell 7(pwsh)是当前的跨平台版本,可在 Windows、Linux 和 macOS 上运行,需要单独安装;两者可以同时安装。7 版新增了命令之间的 && 和 ||、三元运算符和 ?? 运算符,默认以 UTF-8 写入文件,并去掉了 curl 和 wget 等容易混淆的别名。

对象与文本:理解 PowerShell 的关键

在 CMD 和 bash 中,管道传递的是文本。要在 bash 中找出占用内存最多的进程,你得用 sort -k 或 awk 从 ps 输出中挑出正确的列,一旦列布局变化,命令就会失效。在 PowerShell 中,管道传递的是带有命名属性的对象,所以同样的任务写作 Get-Process | Sort-Object WS -Descending | Select-Object -First 1。无需任何解析,而且属性名在每台机器上都一样。

实际带来的变化是一种不同的探索方式。在 bash 中,你要读 man 手册来了解输出格式;在 PowerShell 中,把任意命令通过管道传给 Get-Member,就能看到其对象有哪些属性和方法,再用 Where-Object 筛选、用 Select-Object 选取字段。只有当输出到达屏幕或文件时,PowerShell 才会把它转换成文本。

在 PowerShell 中,ipconfig、git 或 curl.exe 等原生程序输出的仍然是文本,所以 Select-String 和 -match 对它们的作用与 grep 相同。它们的退出码保存在 $LASTEXITCODE 中,而不是 $?。

在三种 Shell 之间转换脚本

简单脚本可以逐行转换,但有几处差异几乎人人都会踩坑:

• 比较运算符:CMD 对字符串用 ==,对数字用 EQU、GTR、LSS;PowerShell 用 -eq、-gt、-lt、-like 和 -match(单独的 > 是重定向);bash 在 [ ] 中对字符串用 =,对数字用 -gt 或 (( ))。

• 变量:CMD 中为 %name%(在执行 setlocal EnableDelayedExpansion 后,循环内用 !name!),PowerShell 中为 $name,bash 中为 $name,赋值时 = 两侧不能有空格。

• .bat 文件中的循环要把百分号写两次:在文件中写 for %%f in (*.txt),在命令行中写 for %f。

• 路径:在 Windows 上,PowerShell 同时接受 / 和 \;Linux 上的 bash 需要用 /。环境变量在 Windows 上不区分大小写,在 Linux 上区分大小写。

• 错误:CMD 在失败后会继续执行,除非你检查 %ERRORLEVEL%;bash 会继续执行,除非设置了 set -e;PowerShell 在遇到非终止错误后会继续执行,除非设置 $ErrorActionPreference = 'Stop'。

如果脚本需要同时在 Windows 和 Linux 上运行,使用 PowerShell 7 或 WSL 下的 bash 可以避免维护两份副本。

相关免费工具

  • Linux 命令速查表 — 按任务分类的 Linux 命令,从文件和权限到网络、systemd 和文本处理。每条都附常用参数、可复制的示例和 macOS 差异说明。
  • Windows 快捷键 — 可搜索、可打印的 Windows 11 全部快捷键:Win 键、窗口贴靠、虚拟桌面、截图、文件资源管理器。
  • Mac 键盘快捷键 — 全部 macOS 快捷键,附 ⌘ ⌥ ⌃ ⇧ 符号说明:截图、窗口平铺、访达、Safari 和特殊字符。
  • curl 转代码 — 粘贴 curl 命令(包括 Chrome 的“Copy as cURL”),即可得到 Python、JavaScript、Node、Go、PHP、Ruby、Java、C#、wget 或 HTTPie 版本的相同请求。
  • Git 速查表 — 按你想做的事整理 Git 命令:撤销上一次提交、重命名分支、删除远程分支。优先给出新式 switch/restore 命令并附经典写法,危险操作有醒目标记。