🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

通过比较来理解PowerShell和cmd的区别【附图解】

一提到Windows的“小黑窗”,很多人可能首先想到的是老旧的“命令提示符(cmd.exe)”。然而,通过之前的文章我们已经了解到,还有一个背景为蓝色、更现代化、更强大的“PowerShell”。这两者看似相似,实则截然不同。

“为什么会有两种?”“到底该用哪个?”“cmd是不是已经过时了?”相信抱有这些疑问的人不在少数。本文将通过具体的任务对比,为初学者通俗易懂地解说这对“老对手”(?)——PowerShell与命令提示符之间的区别。

读完本文,您应该就能清楚地理解为何应当选择PowerShell,以及它压倒性的优势所在。命令提示符这把“锤子”与PowerShell这个“电动多功能工具”之间有何不同,让我们亲眼来一探究竟吧!


最大且决定性的区别:“对象” vs “文本”

PowerShell与cmd最根本的区别,在于命令返回信息的格式。理解这一点,是理解两者差异的关键。

命令提示符(cmd)的世界观:一切皆为“文本”

在命令提示符中输入dir之类的命令,屏幕上显示的只是为了方便人类阅读而格式化的“文本(字符串)”。它就像一张打印出来的清单。要从这份清单中提取出“文件名”或“更新日期”等信息用于后续处理,会非常麻烦,需要复杂的字符串处理。

C:\> dir
 驱动器 C 中的卷是 Windows
 卷的序列号是 XXXX-XXXX

 C:\ 的目录

2024/07/07  09:00              Program Files
2024/07/07  09:05              Users
2024/07/07  09:10              Windows
               0 个文件              0 字节
               3 个目录  123,456,789,012 可用字节

这个输出结果只是一串“字符的罗列”,对于程序来说是缺乏结构的数据。


PowerShell的世界观:一切皆为“对象”

另一方面,在PowerShell中执行类似的命令Get-ChildItem,返回的则是结构化的“对象”集合。所谓对象,是包含了各种信息(属性)的数据块。

【概念图】Get-ChildItem返回的其中一个“文件对象”,就井然有序地存储了以下信息:

这就好比一张信息整理得井井有条的Excel表格。正因为有这样的结构,PowerShell才能以惊人的简便性,实现“按大小降序排列”或“只显示扩展名为.txt的文件”等基于数据的灵活处理。

PS C:\> Get-ChildItem

    目录: C:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024/07/07     09:00                Program Files
d-----        2024/07/07     09:05                Users
d-----        2024/07/07     09:10                Windows

虽然看起来相似,但最重要的一点是,其背后处理的数据质量完全不同。


实践对比:通过具体任务来比较

让我们通过一个稍复杂的任务来比较两者:“从当前运行的服务中,只显示名称中带有'Windows'的服务,并按名称排序”。

在命令提示符(cmd)中的挑战

想用cmd实现这个目标非常困难。虽然可以用net start获取服务列表,但结果只是纯文本。要从中提取包含特定字符的行,并进一步排序,需要灵活运用findstrsort以及复杂的for循环,对初学者来说几乎是不可能的。

C:\> net start
下列 Windows 服务已启动:

   Application Host Helper Service
   Background Tasks Infrastructure Service
   Base Filtering Engine
   ...
   Windows Audio
   Windows Connection Manager
   Windows Defender Antivirus Service
   ...

想从这堵文本墙中准确地提取出所需信息,可谓难于登天。


PowerShell的华丽解决方案

换作PowerShell,得益于对象和管道,只需一行就能直观地写出这个处理过程。

Get-Service | Where-Object { $_.DisplayName -like "*Windows*" } | Sort-Object -Property DisplayName

这一行代码按顺序执行了以下操作:

  1. Get-Service: 获取所有服务作为“对象”。
  2. |: 将获取到的对象集合传递给下一个命令。
  3. Where-Object ...: 从传递过来的对象中,筛选出显示名称(DisplayName属性)包含 "Windows" 的对象。
  4. |: 将筛选后的结果再传递给下一个命令。
  5. Sort-Object ...: 将传递过来的对象按显示名称(DisplayName属性)进行排序。

通过这个对比,您应该能体会到PowerShell在数据处理方面的优越性及其带来的好处了吧。


命令及语法的区别

为了与cmd兼容,PowerShell允许将一些旧命令作为“别名”来使用。但是,其原生的Cmdlet和语法设计得更现代化、更具一致性。

变量的处理

cmd: set 变量名=值

set MYVAR=Hello World

PowerShell: $变量名 = 值

$myVar = "Hello World"

在PowerShell中,变量名前加$是规则。


条件分支 (if语句)

cmd:

if "%MYVAR%"=="Hello World" (echo Same)

PowerShell:

if ($myVar -eq "Hello World") { Write-Host "Same" }

PowerShell使用如-eq (equal) 或 -gt (greater than)这样更易于理解的比较运算符。


cmd是否已无用武之地?Windows Shell的未来

您可能会问:“既然PowerShell这么方便,那命令提示符是不是就没用了?”答案是:“不,它不会马上消失。但是,所有新任务都应该用PowerShell来完成”。

为了保持与非常古老的系统以及过去创建的大量批处理文件(.bat)的兼容性,命令提示符至今仍被搭载在Windows中。微软完全废止它的可能性很小。

但是,从Windows的标准终端工具“Windows Terminal”的默认设置已是PowerShell这一点也可以看出,微软无疑已将PowerShell定位为未来Windows管理和自动化的核心。

如果您是现在开始学习命令行,那么毫不犹豫地选择PowerShell将是明智之举。


总结

这次,我们通过图解(的意象)对比了PowerShell和命令提示符(cmd)之间的决定性差异。

现在,当您面对Windows的小黑窗时,应该已经清楚为何应选择PowerShell这个“多功能工具”了。PowerShell入门系列到此告一段落,但您的自动化之旅才刚刚开始。请务必在日常工作中引入PowerShell,亲身感受它的强大威力!