上次我写了一篇关于“使用命令行”的文章,算是一个铺垫,我给出一个结论是“命令行并不是什么高级的事物,甚至有时是低效的”。不过,抛开其与 GUI 的优劣对比不谈,我们总可以得出一个基本的结论:命令行是有用的。因而,现在我已经完全接受了将命令行作为日常工作中重要的一环了。对于我来说,他不光是 GUI 工具的补充,更是像 GUI 工具一样同等重要、甚至是更丰富的工具集。

在 Windows 上,在很早以前,大家学习电脑都是从桌面和开始菜单开始的,最后才发现好像程序文件放在哪里都是可以双击运行的。也就是说,桌面和开始菜单中的文件只是程序文件的入口,为了使用便利而添加的一些“链接”,当我们双击一个快键方式时,其最终运行的是对应的安装在磁盘上的程序文件。这也是为什么我们卸载软件需要去控制面板操作,而不是直接在桌面上删除的原因。

命令行也一样,经常我们为了调用某个命令行程序,需要 cd 到指令目录,或者指定命令行程序所在的完整路径。这给使用带来了很大的不便。比如,我需要在当前目录,启用 IIS Express 创建一个临时网站并浏览,就需要执行下面的命令:

“C:\Program Files\IIS Express\iisexpress.exe” “/Path:C:\MyDir /Port:2008 /clr:v4.0”

命令很长,输入起来很累,还很容易出错。

其直接结果就是,我们不会手动去输入它,最终我们不再手动地去使用 iisexpress,正像我们从来没有接触过 iisexpress 那样。甚至某一天,我们可能去到网上搜索或者提问“Windows 上没有一个简洁好用的 Web Server 程序吗”。事实上,不管是 Windows 系统本身,还是像 .NET Framework 这种开发框架,或是 IIS 等这些软件,他们都包含有很多实用的命令行工具。只不过,这些工具通常并没有被很好地使用。

定制的命令行工具集

在安装完 Visual Studio 之后,通常会有这样一个工具:“Visual Studio 命令行工具”,安装 Azure SDK 也是。运行Visual Studio 命令行工具之后,发现它比普通的命令提示符窗口多了很多命令,比如 GuidGen、InstallUtil、MakeCert 等。另一个非常典型的例子就是 Git Windows 客户端了。在安装完 Git 客户端软件之后,会安装一个叫 Git Bash 的程序。运行它之后,不光可以方便地使用 Git 的相关命令,更能使用像 VI、find 等这类在 Linux Shell 中才能找到的工具。

定制的命令行工具集带来的便利,与 GUI 中的桌面和开始菜单所起的作用很类似:用户可以更方便地使用一系列命令行工具,而不再需要去不断地切换工作目录,或者输入冗长的路径。甚至,还可以通过列举所有自定义命令来提供有意义的帮助。很容易想到,制作一个适合于自己使用的“定制命令行工具集”也是一件不错的事,能够极大地提高自己日常工作的效率。

要定制一个命令行工具集也很简单,就是在普通的命令行终端程序(即 Shell )中,通过运行一段提前编写好的脚本,向会话中添加一些特有的支持,以及自定义命令,以及初始化脚本。下面介绍几个常见的技巧,可以为定制命令行工具提供帮助。

命令行终端 Profile 文件

基本所有 Shell 都支持 Profile 文件,也就是启动命令行终端程序时的初始化脚本,Windows 命令提示符也支持。通过编   写或更改已有的 Profile 文件,向其中添加一系列自定义脚本,就可以实现我们定制命令行环境的目的。通常,其语法也与正常的批处理脚本没什么不同。而 Shell 通常支持针对当前用户、当前机器等多个默认会话级别的 Profile 路径。

Windows 命令提示符的默认 Profile 文件位置可以通过在如下注册表键来添加自定义的 Bat 批处理文件的位置即可完成对命令提示符的自定义:

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun

PowerShell 支持的 Profile 种类则更多,我们平常使用的最多是针对“当前用户”的 Profile 文件,位于:

C:\Users<UserName>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Linux 的 Shell 也允许多种 Profile,通常需要关注的也就是当前用户 Profile,其位于:

~/.bash_profile


如果按照上述方式修改 Profile 文件,则会导致每次启动 Shell 时,就会运行对应的 Profile 中的脚本。有时我们可能会有“临时”地启动一个初始化脚本这样的需求,比如你向别人提供一个自定义命令行工具集的时候,不希望破坏对方计算机中的设置。这时,我们可以通过显式地指定 Shell 在启动时要执行的命令来达到目标。

在 Windows 命令提示符(cmd.exe)里,可以向其传入 /K 参数(cmd 所支持的所有参数形式,请输入 cmd /? 来查询),如:

cmd.exe /k “C:\WorkSpace\MyProfile.bat”

而在 PowerShell 里,也一样简单:

powershell -NoExit -Command “C:\WorkSpace\MyProfile.ps1”

上述命令可以直接在已有命令行窗口中运行,也可以在 Win + R 的运行窗口中运行,还可以保存为一个 bat 批处理文件,或者固定到开始界面和任务栏,随时启动自己的定制化命令行窗口。显然,使用这种方式自定义配置、并运行起来的命令行环境能成为“自定义命令行工具集”,仅当运行它时,才会应用自定义 Profile 脚本,并且不影响计算机中的默认命令行 Profile。


上面介绍了如何应用自己的自定义 Profile 脚本。那么在自定义 Profile 脚本里,我们应该写些什么来定制我们的命令行环境呢?一般情况下,我们可能会通过对命令行环境执行导入更多工具程序、定义新的函数,以及添加名字别名来增强其可用性的目的。

导入工具集

也就是导入你要增加的一系列软件,令其能够在命令行中被直接调用。比如,向 PowerShell 导入了 nuget.exe 之后,便可以直接使用 nuget install 命令在任何目录安装包了;Windows 内置的很多程序都已经被导入,比如 attrib、ipconfig 等。

要导入新的软件很简单。在 Windows 中,只要将需要导入的软件或程序文件(如 exe、com、ps1、bat)所在目录的路径添加到系统 PATH 环境变量中即可。

在 Windows 批处理文件中,通过以下语句添加一个 PATH 位置 C:\MyPath:

@set “PATH=C:\MyPath;%PATH%”

PowerShell 语句是:

$env:Path += “;C:\MyPath”

在 Linux Shell 里,可使用类似的语句:

export PATH=“/path/to/MyPath:$PATH”

定义函数

将一系列操作定义出来,作为一个函数随时供调用,这样可以提高效率。比如,“向系统 hosts 文件写入一个记录”是我们经常会遇到的情景,我们就可以声明一个函数,以后每次从命令行调用 add-hosts 命令即可。整个过程包括打开文件、写入记录,并关闭文件的多个操作,因此很适合定义函数。

Windows 批处理里中可以定义函数,但函数仅供批处理文件内部调用,似乎并没有方法可以定义一个可以从外部调用的函数。不过,我们仍可以将需要定义的函数保存为一个个的 bat 文件,并使用上一节所述的“导入工具集”的方法将其导入到命令行环境中。而在 PowerShell 脚本和 Linux Shell 文件中,定义函数都是非常简单易行的事。

函数一经定义,即可在命令行终端程序运行其间随时可用;它们还可以处理输入参数,并能够返回值。当然,如果有多个命令行环境,你当然也可以声明一个函数,随时调用它从当前命令行环境来进入其他命令行环境。比如,在命令提示符中输入 powershell 之后也就进入了 PowerShell 模式。

命令别名

有些我们经常使用的命令,但由于各种原因,不太容易找到它们。比如,它们有很深的磁盘路径(或者它的路径中有空格、汉字),命令本身很长或者有很多参数等。这种情况给日常的使用带来了很多不便,就像文章开头所说的 iisexpress 那样。另外,经常在各个不同命令行环境中有相同(近)功能的命令,但它们自身的命令名不一致,而经常在多个命令行环境中切换的你希望有一致的体验。比如 Windows 命令行中的 cls 命令和 Linux 中的 clear 命令。

为了解决这些需求,各个命令行环境都提供了命令别名的能力。也就是使用一个新的名字,用于替代其原来的调用方式,而调用结果是完全一致的。

在 Windows 批处理中,可以使用 doskey 命令设置别名;PowerShell 中不但提供了 Set-Alias 命令用于设置别名,还将内置的很多命令设置了很贴心的别名,如 cls = clear = Clear-Host, 可以通过 Get-Alias 来查看所有别名。Linux Shell 提供了 alias 命令,向其传入表达式即可轻松添加别名:

alias gs=‘git status’

总结

有某个时刻,面对电脑上那许多的程序,我会感觉似乎这台电脑是它们的。毕竟,是它们一天到晚运行着,还要求我去 XX 位置更新 YY 文件,再执行 ZZ 操作,似乎我是那个被他们使用的可怜的人。尤其当安装了一个不受我控制的软件时,这种感觉最强烈。一个随时可由自己操控的电脑很重要。这种掌控感最强烈的时候,大概就是当你在某一个位置随时就能把电脑里任何程序调用起来,并且看着它们顺利地完成工作的时刻吧。

总之,一个好用的、只为你独家定制的命令行环境,你值得拥有。