像黑客一样使用命令行(1)

虽然如今计算机图形化界面大行其道,然而在计算机诞生之初却是命令行界面的天下。在图形化界面中,我们惯常使用鼠标来操作图标或窗口,从而完成各种任务。对于命令行界面来说,情况则有很大的不同。要在命令行界面下执行操作,我们需要更多的依赖键盘。那么,什么是命令行界面呢?在回答这个问题之前,不妨让我们先来谈谈控制台、终端、终端模拟器、以及 Shell 这几个基本概念。

控制台

控制台(Console),又称为系统控制台(System console)、计算机控制台(Computer console)、根控制台(Root console)、以及操作员控制台(Operators console)。事实上,早先的控制台是一种用来操作计算机的硬件,如图 ref(fig:ibm-1620-model-1) 所示。[1]从这幅图片中,我们可以看到 IBM 1620 计算机的控制台由左边的操作前面板(参考图 ref(fig:ibm-1620-model-1-front-panel))和右边的打字机组成。通过控制台,操作员将文本数据或待执行的指令录入到计算机,并最终通过计算机读取或执行。

随着计算机的发展,控制台从硬件概念变成了一个软件概念。于是,控制台有了新的称呼:虚拟控制台。虚拟控制台正好与物理的控制台硬件相对。通过观察 Linux 系统的启动过程,我们不难发现:在经过计算机硬件自检之后,一旦由引导载入程序接管,不一会儿便会进入系统控制台。在这个过程中,通常会显示如图 ref(fig:linux-booting) 所示的 Linux 系统引导信息。[2]

终端

跟控制台一样,起初的终端(Terminal)也是一种计算机硬件设备。从外形上看,终端类似于我们今天所看到的显示器和键盘的结合体。通过终端,用户将指令和数据输入到计算机。同时,终端也将计算机执行的结果展示给用户。图 ref(fig:dec-vt100) 中显示的是曾经广为流行的终端 DEC VT100。[3]

或许你会产生疑问,为什么会出现终端这种硬件设备呢?以今天的眼光来看,显得似乎有些难以理解。诞生之初的计算机造价相当昂贵,可不像现在人人都能拥有一台那么简单。除了大型商业组织或大学研究机构,很难在别处看到计算机的身影。为了能够共享计算机资源,终端应运而生。然而,伴随着科技的进步,终端最终掉进了历史的黑洞。不过,它后来却以新的形式重生,这就是终端模拟器(Terminal emulator),或称之为虚拟终端。

终端模拟器

终端模拟器,即用来模拟终端硬件设备的应用程序。在物理终端中存在的某些显示体系结构,比如用来控制色彩的转义序列、光标位置等在终端模拟器中也得到了支持。图 ref(fig:xterm) 显示 Linux 中流行的终端程序之一 XTerm。

不管是 Linux 操作系统,还是 macOS 操作系统,乃至 Windows 操作系统,今天都有许多终端模拟器可以选择。以下罗列的是这三个操作系统中比较流行的终端模拟器。

Linux

  • XTerm:XTerm 是 X 窗口环境的默认终端。它提供了与 DEC VT102 和 Tektronix 4014 终端兼容的特性。此外,它也支持 ISO/ANSI 彩色模式。
  • GNOME Terminal:GNOME Terminal 是 GNOME 桌面环境的默认终端。它提供了与 XTerm 相似的特性。除此之外,它也包括支持多配置、标签页、鼠标事件等其它功能。
  • Konsole:Konsole 是 KDE 桌面环境的默认终端。它包括标签页、多配置、书签支持、搜索等特性。
  • rxvt-unicode:rxvt-unicode 原本克隆自 rxvt,但加入了 unicode 支持,具有很强的定制特性。另外,rxvt-unicode 还包含 Daemon 模式、嵌入了 Perl 编程语言等功能。本书作者使用的就是这款终端模拟器。

macOS

  • Terminal.app:Terminal.app 是 macOS 操作系统默认的终端。它的功能不多,除了提供设置 TERM 环境变量的选项外,还包括能够使用其搜索功能来查找 Man pages。
  • iTerm2:iTerm2 是 macOS 系统上针对默认终端的开源替代品。它非常流行,包含许多很棒的功能,比如窗口分割、自动补全、无鼠拷贝、粘贴历史等等。如果你在 macOS 上工作,那么不妨使用 iTerm2 这款终端模拟器,相信它所具有的功能一定不会让你失望。

Windows

  • Mintty:Mintty 是一个支持 Cygwin、MSYS、WSL 等多种环境的终端模拟器。它的功能与 XTerm 兼容,包括 256 色和真彩色、unicode、以及 Emoji 表情支持。
  • ConEmu:ConEmu 是 Windows 上一款相当流行的开源终端模拟器。它包含标签页、多种图形窗口模式、用户友好的文本块选择等功能。

Shell

Shell 是一种命令解释程序,它负责用户输入命令的读取、解析和执行。现代 Shell 除了具有与用户直接交互的特性之外,通常也包含编程功能,支持变量、数组、函数、循环、条件等编程基本要素。

Shell 之所以如此称呼,是由于它相对 Unix 及 Linux 的核心——内核(Kernel)而言,处于整个操作系统的最外层,就像乌龟的壳一样。也正因为如此,Shell 提供用来访问系统服务的用户界面,扮演着与内核交互的角色,如图 ref(fig:shell) 所示。

在 Unix 及 Linux 的发展过程中,出现了许多种 Shell,其中比较知名的包括:sh、csh、ksh、bash、zsh 等等。

sh

sh,即 Bourne shell,它是 Unix 第 7 版的默认 Shell。Bourne shell 由贝尔实验室的 Stephen Bourne 开发,于 1979 年发布。随着《Unix 编程环境》(Brian Kernighan 与 Rob Pike 著)一书的出版,sh 变得大为流行。

Bourne shell 早已被后来的 Shell 所取代,现代 Linux 系统中的 sh 通常是符号链接的某个兼容 Shell。例如,本书作者所用的 Debian 9 里的 sh 为 dash。

root@toydroid:~# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24  2017 /bin/sh -> dash

而在作者的另一个系统 Arch Linux 上,sh 则为 bash。

root@codeland:~# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb  7 15:15 /bin/sh -> bash

csh

csh 是 C shell 的简称,它由 Bill Joy 开发,通过 BSD 得到了广泛的分发。在风格上,开发者将 csh 设计得像 C 编程语言一样,因而由此得名。同时,csh 具有很不错的交互使用体验。后来被其它 Shell 所吸收的诸如历史、别名、目录栈、文件名补全、作业控制等特性均出自 csh。

csh 有一个改进版本叫 tcsh,目前是 FreeBSD 的默认 Shell。

ksh

ksh 指 Korn Shell,其开发者为 David Korn,在 1983 年公布于世。ksh 遵循 POSIX 标准,能够向下兼容 Bourne shell,整合了来自 C shell 的诸多特性。ksh 的一大亮点是引入了 vi 和 Emacs 风格的命令行编辑模式,使用户完全可以按照自己的按键习惯操作。此外,在 ksh 中还增加了关联数组的特性。

由于 ksh 最初以私有软件的形式进行分发,从而被限制了传播。代之以出现的替代品包括 pdksh(public domain ksh,公有域的 ksh)、mksh(后成为 Android 的默认 Shell)等。

bash

bash 作为理查德·斯托曼 GNU 工程的一部分出现,从它诞生之初就是为了用来取代 Bourne shell(参考 ref(sh) 节)。Brian Fox 开发了最初的 bash,首个版本发布于 1989 年。如今,bash 已变得十分流行,它是大多数 Linux 发行版以及 macOS 的默认 Shell。此外,通过 WSL(Windows Subsystem for Linux),在 Windows 10 中也可以安装并使用 bash。

bash 的名称来自于 Bourne-again shell,它也遵循 POSIX 标准,其特性吸收自 sh、csh、ksh 等多种 Shell。

zsh

zsh 是 Z shell 的简称,最初的版本由 Paul Falstad 所开发,发布于 1990 年。zsh 极大的扩展了 Bourne shell 的功能,并包含来自 tcsh、ksh、bash 等 Shell 的特性。

在交互用户体验上,zsh 尤其出彩。比如,它支持对命令的选项进行补全、可以设置右提示符等,如图 ref(fig:zsh-prompt) 所示。

本书主要讨论 bash 和 zsh 这两种目前市面上最流行的 Shell。


  1. https://en.wikipedia.org/wiki/System_console#/media/File:IBM_1620_Model_1.jpg ↩︎

  2. https://en.wikipedia.org/wiki/Linux_console#/media/File:Knoppix-3.8-boot.png ↩︎

  3. https://en.wikipedia.org/wiki/Computer_terminal#/media/File:DEC_VT100_terminal.jpg ↩︎