付费栏目万字解析

「万字解析」是体验少数派付费栏目内容的最佳方式。我们希望用一万字的篇幅,系统、深度地分享有价值的内容,让少数派读者可以享受获得新知的愉悦。

本期「万字解析」内容选自《生产力超频:Windows 命令行实用手册》,作者 @Mirtle 介绍了人人学得会、事事用得上的命令行工具,希望让新手入门,高手进阶,掌握强大的命令行工具,成为让 14 亿 Windows 用户羡慕的效率高手。

📍前往了解栏目

📍前往了解新知探索家

 

📍小提示:本文内容较长,章节数较多,建议配合目录跳转至自己感兴趣的章节阅读。


绝大多数的读者使用 Windows 的过程中,难免会遇到个别问题需要求助于网络,譬如浏览器突然打不开百度首页时,此时某条资料会建议:

搜索「命令提示符」,双击打开,在弹出的窗口输入 ping baidu.com,看看能不能 ping 通。

有些读者在更新到 Windows 11 后,不习惯新右键菜单,找不到换回旧菜单的选项,此时会在网上的资料中发现这样的方法:

以管理员权限运行 cmd.exe,输入,reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve,然后重启资源管理器或者重启电脑即可。

打开一个黑黝黝的窗口,输入一串似乎有规则可循的文字,最后完成任务。它显著区别于我们日常所习惯的键鼠交互模式,也是本系列文章的主角:命令行界面(Command Line Interface,缩写 CLI),本文简称其为命令行。

部分读者可能对命令行有着敬而远之的心理,这不难理解。在无数的科幻电影中,黑客们对着老式主机猛敲键盘,顷刻之间改变时局,颠覆世界。

可惜,我无法传授给大家这样的本事,那些影视片段大都是唬人的。但是从另一方面考虑,命令行不是战斗机,也不是坦克,它只是家里仓库里停放许久的一辆皮卡,平时或许不会想到它,需要的时候依然皮实耐用。

然而电影里的有一幕镜头十分贴切:《黑客帝国》中 Mouse 小哥指着黑底绿字的屏幕说:「一个红衣女郎」,初来乍到的 Neo 一愣,吃惊于 Mouse 竟然能看懂屏幕上看似没有任何条理的文字。

希望看完这篇文章后,你也能初步了解看似高深、实则简洁高效的命令行工具。

图片来自 Wikipedia

什么是命令行:使用应用的另外一种方式

在许多 Windows 用户的眼中,命令行是神秘的,它似乎和日常用到的各种软件应用毫无关联。但恰恰相反,命令行非常普通,它仅仅是使用应用的另外一种方式而已。

不妨用一个最常见的场景来举例:在 Windows 上打开 Word。绝大多数人都会找到桌面的快捷方式,或者在开始菜单中搜索应用名「Word」,然后双击,轻松完成任务。

还有少部分人会知道一串快捷键:Win + Ctrl + Shift + Alt +W,按下后系统会直接打开 Word,所有修饰键一起按下被称为 Office 键,再按下不同的字母会直接打开不同的 Office 套件。

当然,同时按下这么多键会让你手抽筋,更有效的做法是右键快捷方式 > 属性 > 快捷键,为这个快捷方式设定一套按键组合。此时,当焦点位于桌面时,按下设定好的按键,也能启动应用。

然而在 1990 年,Windows 开机后并不会进入桌面,用户也没有开始菜单可以点击,只有一个界面上干净利落的 MS-DOS 系统等待着你的输入。

此时,键入 Word,按回车,便能启动 Word 应用:

图片来自:winworldpc.com

Windows 上保留了一个类似于 MS-DOS 的应用——命令提示符(cmd.exe)。我们暂且不管它到底是什么,先来体验如何用命令行打开 Word。在 Windows 上搜索「cmd」并打开该应用。

首先要做的是导航到 Word 应用所在的文件夹。这就像使用一些绿色软件时,因为它们安装时不会创建快捷方式,用户必须先用文件资源管理器找到 exe 文件所在的目录。只不过这一次我们用的是命令:cd,你可以将它理解为英文 change directory 的缩写,cd 后跟上空格以及 Word 所在的目录(不要忘了两边的引号)回车确认执行:

cd "C:\Program Files\Microsoft Office\root\Office16"

然后再输入 Word 的应用名:winword.exe,回车后 Word 便启动了:

回顾我们上面提到的三种打开 Word 的方法:

  1. 第一种使用的是 Windows 提供的图形用户界面(Graphical User Interface,GUI,/ˈɡuːi/),我们看到的是各种按钮,用鼠标辅以键盘来和这些控件交互;
  2. 快捷键往往是对 GUI 的辅助,它之所以会存在,最重要的原因就是用鼠标点太麻烦了,特别是对于 Photoshop 这类功能繁多的的应用而言;
  3. 第三种是命令行。

孔乙己曾向众人卖弄道:「回字有四样写法」,不同的写法实际上表达的都是同一种字。命令行、快捷键、键鼠操作其实也是同样的道理,它没有什么神秘和特别的地方。故宫有许多门,每一个门都能进入宫殿内;应用有许多种使用的方法,鼠标辅以键盘、快捷键、命令行都是和应用交互的一种途径,仅此而已。

为什么我们要使用命令行:功能强大、组合灵活

既然都是操作应用的一种方式,那么我们为什么还放着简单快捷的图形界面不用,「返璞归真」地用命令行呢?这就要提到命令行的两大优势:功能强大、组合灵活。

根据模版创建 Word 文档

仍以 Word 举例,假如我们需要 Word 不显示启动界面,且用现成的模板新建文件呢?

例如我的 D 盘上有一份荣誉证书模板 d:\honor.dotx,我需要以此模板为基础,制作二十份不同学员的证书:

注:模板来自 office 官网

图形界面确实可以实现:为了不显示启动界面,我们需要在 Word 的选项中仔细搜寻一番对应的设置;从模板新建文档需要双击图标启动 Word,找到 D 盘中的模板,最后在新建菜单中双击模板。二十份的话重复二十次即可。

在命令行中,我们仍然需要打字:同样是打开 cmd 并导航到 Word 目录,这次输入的是 winword.exe /q /td:\honor.dotx,细心的读者估计已经能猜出 winword.exe 后的两个小尾巴的意思:q 自然是指 quiett 后面既然是模板的路径,那可能代表着 template,整句话就像在发号施令:

  1. winword.exe 听令:启动;
  2. 启动时请不要显示启动界面;
  3. 直接用模板 d:\honor.dotx 新建文件。

「很酷,可惜打这么多字也没简单多少。」你可能这样想。但命令行神奇之处就在于:看似它只能用在黑漆漆的命令提示符里,实际上却无处不在。

我们右键 Word 的快捷方式选择属性,其中有一个「目标」栏写着 Word 的应用路径。给它后面添加上我们刚刚写的两个小尾巴,目标栏此时的值应该是 "C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE" /q /td:\honor.dotx应用后,再双击,现在这个快捷方式就能完美地达成我们的需求了:

下载 B 站视频

从 Word 示例中可以看出,常用的软件同样提供了命令调用的方式,并且可以让日常办公生活方便一点点。其实,还有许多命令行工具提供了许多图形软件所不具备的功能。

比如说我们在 Bilibili 上看到一个视频,非常喜欢,想要下载收藏,或者想要用在自己的作品中。目前大部分视频网站都不再提供下载为通用格式的功能。下面我们用到的是视频下载工具 yt-dlp。

和文章一开头提到的 reg.exe 不同,它并非系统内置应用,需要预先下载到本地,就像我们要玩游戏首先得下载安装一样。yt-dlp 的官方下载地址在这里

我建议大家把我们后续下载的小工具全部放到 C:\tools 或者 D:\tools 目录下。下载到本地若双击系统弹出警告,需要先右键文件 > 属性 > 解除锁定

下载其中的 yt-dlp.exe

如果你尝试双击此应用,会直接「闪退」。这是正常现象,它没有图形界面,需要在命令提示符中使用。这类应用其实有个特别的名字,叫做控制台应用(Console App & Terminal App)。

现在我们从开始菜单搜索并打开 cmd.exe,这一次,我们不用 cd 导航到程序所在的文件夹,而是直接写出应用的全名,也就是它的完整路径。

获取应用路径的方法有两个,其一是右键文件(Windows 10 需要按住 Shift 再右键),选择「复制文件地址」,最后在 cmd.exe 窗口上右键点击以粘贴

注意,在 cmd 中,点击鼠标右键不会呼出一套图形化菜单,Ctrl+V 也不起作用。选中文本按右键是复制功能,不选中文本按右键是粘贴功能,这是以后会经常用到的技巧。

我更加推荐第二种方法:直接把文件拖动到命令提示符窗口上:

我们以少数派的视频为例,复制视频的地址(在 Chrome 中,可以按住 Ctrl,依次按 L,C 键),最后在命令提示符窗口把链接粘贴到 yt-dlp 的全名后面,最终命令是:

D:\Tools\yt-dlp.exe https://www.bilibili.com/video/BV1jS4y1o7Fc

回车,执行,不过一会儿视频就会下载完毕:

整个过程很简单对吧?我们甚至没有打过一个字母。

不过,视频下到哪去了?默认情况下,yt-dlp 会在视频存在当前的目录下,也就是我们每次输入命令前都显示的那个目录,在上面就截图中,就是 C:\User\KepaC:\User 下面的这个以用户名命名的子目录又被称为 Windows 的用户目录,之后我们还会提到。

我不太满意默认下载的位置,想着直接下载到 D 盘的 Videos 文件夹多好。另外我还想存一份视频的封面图。就像 Word 示例一样。

此时我们需要给命令加小尾巴,这个小尾巴的正式名称多种多样,比如说参数(parameters,arguments)、标识(flags)、开关(switches)、选项(options)等等,本系列文章统一使用参数指代,它的作用就是规定应用具体应该如何完成我们给的指令,类似于语法中的修饰成分,比如说本例:

D:\Tools\yt-dlp.exe https://www.bilibili.com/video/BV1jS4y1o7Fc --output D:\Videos\sspai_test.mp4 --write-thumbnail

相较于前面的命令上面这行长了不少,但同样不难理解。前面还是命令加链接,只不过后面多了两个参数,-- 号的作用和第一个例子中的 / 是一样的,表示「这后面的是参数」,整行命令翻译成自然语言:

  1. yt-dlp.exe 听令:你去下载 https://www.bilibili.com/video/BV1jS4y1o7Fc
  2. 将视频输出到 D:\Videos\sspai_test.mp4;
  3. 同时保存视频的封面。

不过不得不承认,图形界面完成不了的需求还是少数,似乎绝大多数情况下图形界面简单直观。特别在 Windows 这样一个图形界面做得非常完善的系统下,没必要给自己找麻烦。但微软仍然没有抛弃看似传统落后的命令行,能让微软留住开发资源的原因,是命令行那无与伦比的灵活性和自由组合的能力

而命令行能轻松地批量处理各类任务,实现的方式之一就是脚本。

安装和管理命令行工具

截至目前,本文已经向大家介绍了几个通过命令行形式使用的应用,每一次我都会让大家从官方网站下载,解压,然后移动到 tools 文件夹,再将应用所在目录添加到环境变量的 Path 中,用起来比普通的 GUI 还要更麻烦一点。有没有方法可以省心省力一点,把这些流程自动化呢?

结合上一章中对脚本的阐述,读者可能马上就会想到:把这些过程编写成脚本不就行了?这其实就是 Windows 下的包管理器了。在 GitHub 上搜索 Windows 平台三大包管理器(ChocolateyScoopwinget)的软件库,不难发现它们提供的并非安装包,而是脚本。

包管理器是对于普通人来说最为实用的命令行工具。它们可以帮助你批量安装、卸载、升级 PC 中的应用,无需再去官网获得安装包。对于前面的例子中,需要手动添加进环境变量的应用,包管理器也会自动帮你处理好。

Windows 平台主流的三个包管理器中,

  • winget 由微软开发,它可以直接安装 Microsoft Store 中的应用;
  • Scoop 有社区自发维护,志愿者多,含有许多的小众应用资源;
  • Chocolatey 由商业公司维护,库中应用最多,CLI 功能也最丰富。

值得一提的是,除了 Scoop 有社区维护的国内镜像,其他平台的包管理都会用到服务器位于大陆之外的网络资源,因而默认情况下载速度不太理想。这一小节会以 Chocolatey 为例介绍包管理器的各种用法。

按照官网的教程,在保证网络通畅的情况下,搜索 PowerShell,并以管理员权限打开。我们会在后面几章中详细介绍 PowerShell,目前读者可以讲它理解为类似于 cmd 的应用,它们就像做同一个业务的两个不同的职员,虽然都能运行命令,但做事方法和风格大不相同。我们在 PowerShell 中逐条粘贴并运行下面两条命令:

Set-ExecutionPolicy Bypass -Scope Process -Force
iex ( irm 'https://community.chocolatey.org/install.ps1' )

等待进度条走完,此时 Chocolatey 已经安装完毕,试着输入 choco -? 会有以下输出:

下面需要用 choco 来搜索一下我们之前用到过的几个小工具。搜索 ytp-dl 的命令是:

choco search ytp-dl

你可能觉得这个搜索结果不那么准确,另外结果里面有太多不相干的内容,此时就可以用上参数。-r 参数会让输出不显示无关内容,而 -e 参数代表仅显示完全匹配的条目:

一些读者可能非常在意空格问题。空格只是其分隔作用,无论有多少都无所谓。比方说,我想查看 youtube-dl 的具体信息,执行 CHOCO info YOUTUBE-DL 也是完全没问题的。

安装的命令是 choco install,卸载是 choco uninstall,升级为 choco upgrade。我们还能用 choco export 将所有安装的应用导出为列表,再用 choco import 导入重装:

choco install youtube-dl -y # 安装一个应用:youtube-dl,不加 -y 参数会要求确认
choco install adb youtube-dl typora -y # 安装三个应用
choco uninstall adb -y # 卸载 adb
choco upgrade adb # 升级 adb
choco upgrade all # 升级全部软件
choco export D:\chocolist.config # 导出所有应用列表为 chocolist.txt
choco import D:\chocolist.config # 安装 chocolist.txt 中的所有应用

此外,我们可以使用 config 命令设置 http 代理:

choco config set proxy http://127.0.0.1:12345 # 设置代理为 http://127.0.0.1:12345
choco config unset proxy # 取消设置代理

读者务必熟悉 Chocolatey 和 scoop 包管理器的基本操作,因为接下来如果使用到其他命令行应用,我不会再像本文一样详细地给出安装下载的方式,大家需要用 CLI 的方式安装它们。

Chocolatey 其实提供了 GUI 版本(choco install ChocolateyGUI -y),读者可以尝试一番,但想必不过多久就会用回命令行,毕竟 CLI 的资源占用和流畅度一定会比封装后的 GUI 好上不少。

运行命令行工具和命令的「终端」到底是什么?

前文中我们介绍了许多命令行工具,但在使用这些工具之前,我们都要打开 cmd 或 PowerShell,它们到底是什么?

之前我们提到了 Windows 的前身,MS-DOS,这是一个只能通过命令行操作的古老系统。而所谓系统,本质上也是一个软件,但通常的软件是系统和用户的中介,例如我们没办法不开机就使用 Office 办公套件,用 Word 编辑一个文档必须先让 Windows 启动。

但系统中的某些部分不一样,它直接和硬件打交道,用户和软件都通过系统这个中介来使用硬件资源完成任务。在系统,软件,用户这三个角色中,系统中负责调度硬件的那一部分离核心最近,地位最核心,因而有了一个形象的名字:内核(Kernel)

类似于一个坚果,有内核必然有外壳。最早人们既然用命令行的方式和系统交互,那么能运行命令的东西也自然就成了壳(shell)

Windows 上的 cmd、PowerShell 是 shell 的一种。此外,Linux 和 macOS 上有各种各样以 sh 结尾的应用,例如 bash、zsh、fish 以及 csh,其中的 sh 就是 shell 的缩写。所以这些单词会有三种读法:

  1. 第一种是字母本音 +[ʃ],例如 zsh 可以读成 [ziːʃ];
  2. 第二种是把 sh 发成 shell,例如 csh [siʃel];
  3. 至于 bash、fish 等本身是一个单词的,都会发单词音。

shell 还有一个更加形象的名字:命令行解释器。我们已经遇到过一些命令:cd 会进入某个目录、del 能删除文件。这些命令很大程度上从自然语言精简而来,显然,操作系统并不能理解人类的语言,而 shell 把 cd、del 等命令翻译成计算机能读懂的语言,它在用户和系统间充当了翻译官的角色。

因而也可以想见,不同的 shell 是不同的语言之间翻译官。一条命令可以在 PowerShell 中执行成功,但 cmd 却可能会报错。例如,在 PowerShell 中执行 ls(list 的简称)可以列出当前目录下的所有条目,但 cmd 却不认识这个命令:

bash、zsh 等 Unix-like 系统上的 shell 和 PowerShell 更是有天壤之别,虽然有少部分知识是相通的,但 Windows 上学习了 PowerShell 后,仍然需要再系统地学一遍其他平台的 shell 操作,反之亦然。

不过虽然这么说,仔细观察不难发现,cmd 和 PowerShell 的窗口真是太像了,如果没有菜单栏的图标,你几乎看不出它们的区别。

之所以会这样,是因为我们看到的不是 shell 本体,而是叫做 Windows 控制台(conhost.exe)的应用,它的背后藏着真正的 shell.

Windows 控制台们有着另一个名字:终端仿真器(terminal emulator),简称终端。

不妨做一个类比:微软推出的 Edge 浏览器和 Google 的 Chrome 浏览器基于同一个开源项目:Chromium。我们在地址栏上输入同一个网址后,两个浏览器都会展示同样的网页,这是因为两个浏览器负责渲染网页的核心是一样的。但 Edge 和 Chrome 的右键样式、设置页面、各种按钮等外在却完全不同。

终端和 shell 的关系也非常类似。shell 是命令行解释器,而终端负责提供输入的界面,展示命令的输出。一个 shell 可以连接到各种终端。Windows 默认采用的 Windows 控制台、Windows 11 预装的 Windows 终端、简洁而功能强大的 cmder、采用的 Fluent Design 的 Fluent Terminal 等应用都是终端,都能和 cmd 通信。

拓展:*NIX 系统的确如此,但 Windows 的终端、shell 设计有所不同,Windows 控制台承担着更加复杂的任务,所有第三方终端都要通过 Windows 控制台提供的 API 和 shell 通信,详见微软的说明

不同的终端都运行着 cmd

各类终端不仅 UI 上有所区别,在功能也有所不同。例如,上一篇文章我们提到:在 Windows 控制台中需要选中文本,然后右键才可以复制所选文本。但在 Windows 终端中,用户可以设置选中文本直接复制,无需右键:

下面的演示中,我会一直使用这个更加现代美观的 Windows 终端。没有安装的读者,可以从 Microsoft Store 中搜索下载。之后,在 Windows 设置 > 隐私和安全性 > 开发者选项中,将其设置为默认终端:

综上所述,shell 和终端的定义和区别在于:shell 将用户的输入解释成计算机能够理解的语言,是运行各类命令的地方,不同的 shell 语法不同;而终端是 shell 的可视化界面,掌管着输入和输出,我们可以用 Windows 终端来替代 Windows 控制台以获取更好的体验。

区分外部命令与 shell 命令

搞清楚了不同终端间的区别,我们再来仔细看下终端中运行的不同命令间的区别。

在 Windows 上 cmd 和 PowerShell 是两个完全不同的翻译官,一条命令可以在 PowerShell 中执行成功,但 cmd 却可能会报错。

一些读者可能有疑问:那为什么很多工具既可以在 cmd 上运行,也能在 PowerShell 上运行,并且用法完全一致呢?

事实上,这些工具不只在 Windows 平台语法相同,在 Linux 和 macOS 的 shell 中也是一样的。它们不依赖于 shell 而存在被称为外部命令,与之对应的,是 shell 自带的命令被称为 shell 命令

此外还有一部分跨平台的命令行工具既非外部命令,也非 shell 命令,它们其实是脚本。开发者为不同的 shell 写了不同的脚本文件来保证使用体验一致。

回忆一下第一篇中我们提到的一些例子。ping、Word、yt-dlp、adb、notepad 等等命令,当时我们是在 cmd 中运行的,你可以尝试用 PowerShell 来执行这些命令,可以发现语法、功能都完全一致。

原理很简单。打个比方,Windows 和 macOS 是两个系统操作逻辑大相庭径,但两个系统上的 Chrome 浏览器按钮、菜单、功能大致是一样的。同样的道理,yt-dlp 等外部命令是以可执行程序(exe 文件)形式存在的,命令的参数和功能已经由第三方开发人员预先设计好,无论是什么 shell 都不会影响它们的用法。

我们可以用 where.exe 程序证实上面的说法,它会返回一个外部命令的真实路径。例如,在 cmd 或者 PowerShell 输入 where.exe ping,终端会出现 ping.exe 的路径:

那如何理解 shell 命令呢?外部命令之间没有什么联系,就像 Notepad 和 Word 之间没有关系一样;但 shell 命令类似于 Word 这个应用中的一个个小功能,它们是由同一个开发商为了一个大的目标,用一套规整的逻辑设计出来的。例如,cmd 自带的所有命令的参数都用 / 标记,而 PowerShell 命令的参数则是由 - 标记的。还记得之前用 adb 禁用应用的命令吗?

adb shell pm disable-user com.tencent.mm

有没有想过为什么它这么长?原因在于这行代码做了两件事,adb shell 负责进入 adb 提供的 shell;pm disable-user 才是禁用应用的命令,adb 提供的 shell 中,其他的命令长得都和 pm disbale-user 差不多:

理解命令行的语法

搞清楚了外部命令和 shell 命令,就该好好学习下命令行的语法。

仔细琢磨的话,「学习使用命令行」这个话题似乎有些奇怪。因为命令行应用也是应用程序,类比来看,经常使用手机的用户很少会问「如何使用淘宝」、「如何使用微信」等问题。

可命令行偏偏不同,如果我不在第一篇文章中告诉大家 Word 可以加 /t 参数,你可能从来没想过 Word 可以这么用。因此有一种观点认为,CLI 最大的缺陷就是「可发现性」差。

但事实并非完全如此。之所以许多人会觉得命令行难,是因为他们习惯了另外一种逻辑。还记得第一篇文章中我如何阐述 CLI 作用的吗?

应用有许多种使用的方法,鼠标辅以键盘、快捷键、命令行都是和应用交互的一种途径。

以手机 App 为例,所有手机应用都在一套统一的交互逻辑的框架下:

  • 点击操作意味着确认、进入;
  • 按住操作意味着菜单、更多;
  • 滑动操作意味着滚动内容,移动焦点。

只要理解了点、按、滑这三个基本操作,不用任何人教我们也能掌握一个新 APP 的基本用法。桌面端的应用交互也有类似的逻辑,鼠标左键、右键、中键不正是对应着确认、更多和滑动吗?反过来说,你会觉得各种快捷键记起来很麻烦,背后的原因是不是快捷键背后缺少一套统一的设计逻辑呢?

这就是第一篇所说的「和应用交互的途径」的本质。掌握了点按滑就会使用手机的各种应用,那学会了什么样的逻辑,就学会了所有的命令行应用呢?

和 GUI 不同,命令行中,我们就像写文章一样是通过输入字符来完成任务的,因而使用命令行的逻辑表现为语法(Syntax)。就像所有手机 App 都能点、按、滑一样,无论是 PowerShell、cmd 还是 Bash,所有运行在 CLI 上的命令都遵守着一些共同的语法规范。

我们不妨把之前用过的几个命令写在一起:

yt-dlp https://www.bilibili.com/video/BV1jS4y1o7Fc --output D:\Videos\sspai_test.mp4 --write-thumbnail

choco search youtube-dl -r -e

VirtualDesktop11 /w /right

powershell -nologo -file D:\tools\init.ps1

尽管它们功能、用法大相径庭,但命令的构成却出奇地一致:命令名,动作,参数,它们之间以空格分隔。命令行的语法可以总结为:

命令名 动作 参数1 参数2 参数3 ……

shell 环境下各种命令都能抽象为上面的结构,只不过它们在某些字符的写法和顺序上有所不同,一些命令可能没有后两个部分。我们暂且把命令间的区别放一边,先逐个部分解释其中的共性。

命令名

第一部分是命令名。无论使用什么命令,都必须先叫出它的名字。就像分配任务时,必须先指定负责人一样。对于外部命令而言,命令名就是外部应用的文件名。在前面的学习中,我们既看到过简短如 notepadchoco 的应用名称,也认识到:如果应用所在路径没有加进环境变量,就必须写出应用的完整路径,否则 shell 就会报错:

该输入什么命令名,取决于应用开发者给他的应用起了什么名字,我们能用 where.exe 看到外部命令的具体路径。不过那些自行下载到本地的应用,我们完全可以把它们改成自己喜欢的名字,下图中我就把之前用到过的 yt-dlp.exe 重命名为 yt.exe,执行起来也没有任何问题:

和类 Unix 系统不同,Windows 文件系统不区分大小写,因而应用名也不区分大小写。pingPING乃至 piNG 都是同一个应用:

如果一个应用的完整路径含有空格,必须加双引号。因为一行命令的不同部分之间就是用空格分隔的,如果不加引号,shell 就会把它当作几份分别解析。此外务必记住,和 cmd 不同,PowerShell 在执行加引号的命令时,前面必须加 &(见下图第三条命令),背后的原因我们之后会学到:

动作

第二部分是动作。如果说命令名对应着一句话的主语的话,那么动作部分就相当于谓语和宾语。不同的命令的动作部分可能是类似的,例如 scoop install yt-dlpchoco install yt-dlp 都是安装 yt-dlp 的意思。要想理解一行命令的功能,第一和第二部分是关键,例如 Chocolatey 还原代理的命令:

choco config unset proxy

命令名是 choco,后面都是动作部分,读起来像是一句精炼过的句子:

choco 配置 取消设置 代理

一些应用本身功能单一,命令名本身的意指就非常明确了,那么它就不需要第二部分。譬如第二篇文章中提到的 Chrome,用命令行的方式调用它的时候,Chrome 唯一的作用就是打开浏览器。

参数

真正的难点在于第三部分参数,它的作用是详细规定一个动作要如何完成。很多情况下,学习命令行工具就是在学参数。一个命令可以有几十个参数,它们看似复杂,实际也有规律可循。

参数部分由特殊符号开头。本节一开始列出的四个命令,它们的参数前面是 -(减号)、--(两个减号)或 /(斜杠)这三种特殊符号,后面则是相对贴近自然语言的字母或者单词:virtualdesktop /w /right 的作用切换到右侧的桌面,参数 right 指向右,参数 wWrap 的缩写,表示当切换到最右侧的桌面时,绕回第一个桌面。

在下面这行命令中:

powershell.exe -nologo -file D:\tools\init.ps1 

我们还能发现两类不同参数:-file D:\tools\init.ps1 是常规参数,其结构是 参数名 参数值,也就是说D:\tools\init.ps1file 的具体值。对于常规参数而言,一旦我们写了参数名,往往需要为它指定一个合适的数值:

参数名和参数值的连接方式因应用而异。大多数命令用的是空格,不过也有用 = 或者 : 的案例。譬如用 choco 锁定应用(不进行更新)的命令:

 choco pin add -name=<应用名>

这里用的就是 = 号。

常规参数之外,-nologo 被称为开关参数(switch parameter)。这类参数只有是和否两种状态。如果我们不写 -nologo,那么 PowerShell 就会显示版权信息,反之则会隐去相关信息。choco 命令中的 re 也是类似的道理。

参数的大小写和命令名不同,是由应用开发者控制的。-f-F 极有可能是两个不同的参数,因而在输入参数的时候务必小心。

了解完命令的三大主要成分,在键入命令时你应该会更有信心了。但理解了命令行的语法并不足以帮助我们掌握陌生的命令,我们还需要明确地知道一个命令可以加哪些动作,有哪些参数。

三类不同的命令风格

而在我们接触了这么多命令行工具之后,不难发现,在 命令名 动作 参数 这个组合中,外部命令的前两部分都大同小异,但参数部分则各有特点。根据这些特点,我们可以将外部命令分为三类。了解完这三种「模具」,你便能更快地掌握新的外部命令。

Unix sh 风格

计算机发展过程中,在 Unix 时代几个最为流行的 shell —— sh(bin/sh)、Bash(/bin/bash)影响下,命令行的最初规范逐步确立,之所以 Linux、macOS 等 Unix-like 系统上的各类 shell 命令基本一致,便是因为它们或多或少都遵循着这些习惯。

现代的开发者们在设计自己的应用时,常常倾向于和类 Unix 系统上的 shell 命令风格保持一致。因而,Unix sh 风格的外部命令非常常见。比如说我们刚刚用到的 cURL,通过文档观察其语法和参数:

命令的特点是:

  • 参数大多由 - 或者 -- 开头;
  • - 后接短参数,即一个字母,-- 后接长参数,即完整的单词,多个单词由 - 连接。前者往往是后者的简写形式;
  • 参数名和参数值之间往往由空格或者 = 连接;
  • 参数区分大小写;

以上四点是所有 Unix sh 风格命令的共有特征,如果碰到了这类命令,使用 command --help 大概率能调出其文档。

不只是 cURL,我们用过的 npm、yt-dlp 等大部分应用属于此类风格,比如说当初我们用 yt-dlp 下载视频的命令是:

yt-dlp <url> --output D:\Videos\sspai_test.mp4 --write-thumbnail

命令的文档告诉我们参数 --output 有一个简写形式 -o,因此,它和下面的命令是等价的:

yt-dlp <url> -o D:\Videos\sspai_test.mp4 --write-thumbnail

又因为 Unix-like 风格的命令区分大小写,所以千万不要写成了 yt-dlp <url> -O ……

不过有时候你会看到这类命令的短横线后跟了不只一个字母,比如说 curl -fsSLgit -am,这并没有和 Unix sh 风格冲突, 而是同时指定多个短参数的简单写法:curl -fsSL 等同于 curl -f -s -S -L

Windows cmd 风格

从各种意义上,Windows 都不遵循许多类 Unix 系统奉为圭臬的种种习惯。cmd 是微软从 MS-DOS 基础上拓展而来的 shell,这也造就了 Unix sh 风格之外的 Windows cmd 风格,它的典型例子就是 cmd 本身了:

其特征是:

  • 参数开头是 / 符号,其后既可以是字母,也可以是单词;
  • 参数名不区分大小写;
  • 参数名和参数值之间由空格或者 : 连接。

调出它们的文档的方法是 command /?。除了 cmd,之前我们用过的 Word、VirtualDesktop 都属于此类。实际上,大部分 Windows 预置的外部命令,以及专门为 Windows 写的应用一般都遵循这类风格,例如 Windows 自带的电源管理小工具,powercfg.exe:用它来生成一份电池使用报告的命令是:powercfg.exe /BATTERYREPORT,将参数小写也是没问题的:

相较于一板一眼的 Unix sh 风格,这类的命令设计得非常宽松,一些命令支持省略参数前的 / 符号,或者用 - 代替,这也是为什么大家能在网络上看到同一个命令的各种写法。我仍然建议大家统一地使用 /,因为并非所有应用都支持此特性。

PowerShell 风格

第三种风格的命令更好理解,其特点是:

  • 参数由 - 开头,- 后可以是单词或字母;
  • 参数不区分大小写;
  • 参数名和参数值之间一般用空格分隔。

查阅这类命令文档的方法一般是 command -help,可以缩写为 -h,少数跨平台的应用倾向于使用这种风格,前文展示过的 PowerShell、magick 都属于此类:

这是最简单的一类命令,我们只要记住它的参数是由 - 引导的即可。但它们的缺点是命令写起来往往很长。