当前位置: 首页 > Linux

命令行界面(CLI)、终端(Terminal)、Shell、TTY,傻傻分不清楚?

时间:2023-04-06 01:23:44 Linux

原文发表于本人博客,欢迎订阅。;)为什么突然想写这样一篇文章?其实是因为在最近打算发布的一篇关于WSL(WindowsSubsystemforLinux)的博文中,我打算对终端模拟器和Shell的选择和配置进行说明。但是,对于刚接触Linux或者刚接触命令行界面的同学来说,可能很难理解它们之间的区别(其实我一开始也是这么干的)。虽然这个话题已经是老生常谈了,但一搜应该也能找到不少相关的文章。但是这方面很少提及,所以我就借这个机会写下我的理解,一是看自己是否真的理解,二是看能不能把它们之间的区别讲的更简洁易懂。0.太长看不了TL;DRCommandLineInterface(CLI)=用于与文本命令交互的用户界面Terminal=TTY=文本输入/输出环境Console(控制台)=一种特殊类型的终端Shell=命令行解释器,执行用户输入的命令并返回结果1.什么是命令行界面?命令行界面,通俗地说,就是你见过的那种屏幕上全是字符的界面。命令行界面(英文:Command-lineInterface,缩写:CLI)是图形用户界面流行之前使用最广泛的用户界面。它通常不支持鼠标。用户通过键盘输入指令,计算机接收到指令后执行。.——摘自维基百科相信大家对影视作品中出现的场景不会陌生,黑客/程序员/安全专家坐在电脑前猛敲键盘,满屏都是滚动字符。这种与逐行命令的输入和输出进行交互的用户界面称为命令行界面。▲电影《黑客帝国》的剧照现在已经全面普及图形用户界面(GUI)。在电脑的日常使用中,普通用户几乎不需要手动输入任何命令。大多数操作都可以通过单击鼠标来完成。命令行操作似乎已经成为高质量的代名词。但实际上,仍然有很多软件开发人员、系统管理员或高级用户使用命令行界面来操作计算机。一大原因是效率:在记住命令的前提下,使用命令行界面往往比使用图形用户界面更快。比如我想把当前目录下(包括嵌套的子目录)所有*.tpl文件的后缀改为*.blade.php。不使用命令行怎么办?手动修改肯定不行,不过还是得去网上找相关的软件,还要注意下载源是否靠谱(像我这种有点洁癖的玩家还是要找绿色版的),下载后,您必须手动指定文件路径。命名模板...并使用命令行(这里以Ubuntu上的Bash为例),只需运行:rename's/\.tpl$/\.blade.php/'./**/*.tpl命令行操作效率高的优势,也是很多图形化计算机系统仍然不放弃提供命令行操作的原因。甚至Windows都有自己的命令行程序,例如cmd.exe和PowerShell(实际上,当您搜索“批量重命名”时,可以看到很多解决方案都是通过“Windows命令提示符”实现的)。2.Terminal——人机交互的接口端子(Terminal),这个词本身的意思是“终端站;端点;(电路)端子,电线连接器”。在计算机领域,终端是一种用来让用户将数据输入计算机并显示其计算结果的机器。也就是说,终端只是与计算机交互的输入输出设备,不提供操作处理功能。要全面了解终端,我们还得追溯历史,看看终端的起源。2.1历史上的终端在大型机和小型机时代,以前的计算机非常昂贵,体积庞大,不像现在人手一台。这些笨重的电脑通常安置在单独的房间里,而操作电脑的人则坐在另一个房间里,通过某种设备与电脑进行交互。这种设备称为终端(Terminal),也叫终端机。▲ASR-33电传打字机(图片来源:Flickr-MarcinWichary,CC-BY-2.0)早期的终端机一般是一种称为电传打字机(Teletype)的设备。为什么?因为Unix的创始人KenThompson和DennisRitchie想让Unix成为一个多用户系统。多用户系统就是为每个用户配置一个终端,每个用户都必须有显示器和键盘。但是那时候所有的电脑设备都很贵(包括显示器),而且键盘和主机是一体的,根本没有独立的键盘。然后他们巧妙地发现了一样东西,那就是ASR-33电传打字机。电传打字机虽然最初是用来在电报线上收发电报,但它有键盘,可以发送信号,还可以把接收到的信号打印在纸带上,因此可以作为人机交互设备。最重要的是,它很便宜。:P因此,他们将许多ASR-33连接到计算机上,以便每个用户都可以在终端上登录并操作主机。就这样,他们创造了计算机历史上第一个真正的多用户操作系统Unix,电传打字机成为了第一个Unix终端。想知道用电传打字机作为终端是一种怎样的体验吗?这是一个非常酷的演示视频。2.2.什么是控制台?上面我们说过,从历史上看,终端就是连接到计算机上的具有输入输出功能的外设。但是有一个终端是不同的。它与电脑主机融为一体,是电脑不可或缺的一部分。这个特殊的终端叫做控制台(Console)。顾名思义,控制台是用来管理主机的,只能由系统管理员使用,权限比普通终端大。一台电脑上一般只有一个控制台,但可以连接多个终端。▲左边是Console,右边是Terminal。有很多用户通过终端访问一台计算机,专门管理那些大型机器的系统管理员是其他人。普通用户使用普通终端,系统管理员使用的终端功能更强大,所以叫控制台(笑)。但是随着个人电脑的普及,Console和Terminal的概念也逐渐模糊了。在现代,我们的键盘和显示器既可以看作是控制台,也可以看作是普通的终端。当您管理系统时,它们是控制台;当您进行一般工作(浏览网页、编辑文档等)时,它们是终端。我们自己既是普通用户又是系统管理员。因此,Console和Terminal现在基本上被认为是同义词。2.3有不同类型的字符终端和图形终端。字符终端,也叫文本终端,是一种只能接收和显示文本信息的终端。早期的终端都是字符终端。字符终端也分为哑终端和所谓的智能终端,因为后者可以理解转义序列,定位光标并显示位置,更智能,而哑终端则不能。▲DECVT100终端(图片来源:Flickr-JasonScott,CC-BY-2.0)DEC于1978年制造的VT100,因其良好的设计和第一批支持ANSI转义序列和光标控制的智能终端,赢得了前所未有的成功。VT100不仅是历史上最受欢迎的字符终端,也是字符终端的事实标准。随着技术的进步,图形终端也开始出现在大众视野中。图形终端不仅可以接收和显示文本信息,还可以显示图形和图像。著名的图形终端是Tektronix4010系列。不过现在专用的图形终端已经极为少见,基本已经被全功能显示器所取代。2.3.终端仿真器(TerminalEmulator)随着计算机的进化,我们已经看不到专用的终端硬件,取而代之的是键盘和显示器。但是没有终端,我们如何与那些不兼容图形界面的传统命令行程序(比如GNU工具集中的大部分命令)进行交互呢?这些程序不能直接读取我们的键盘输入,也没有办法在我们的显示器上显示计算结果……(这里就不说图形界面的原理了,编程的时候图形界面还是在妈妈的子宫里!)这时候我们就需要一个程序来模拟传统终端的行为,那就是终端仿真器(TerminalEmulator)。严格来说,TerminalEmulator的译名应该是“终端仿真器”。对于那些命令行(CLI)程序,终端仿真器“假装”为传统的终端设备;对于现代图形界面,终端仿真器“假装”为GUI程序。终端仿真器的标准工作流程是这样的:捕获你的键盘输入;将输入发送到命令行程序(程序会认为它是来自真实终端设备的输入);获取命令行程序的输出(STDOUT和STDERR);调用图形接口(如X11)将输出渲染到显示器。终端模拟器有很多,这里举几个经典的例子:GNU/Linux:gnome-terminal、Konsole;macOS:Terminal.app、iTerm2;Windows:Win32console、ConEmu等▲我使用的终端模拟器:Hyper和wsl-terminal麻烦。2.4终端窗口(TerminalWindow)和虚拟控制台(VirtualConsole)大多数终端仿真器以图形用户界面(GUI)运行,但也有例外。例如在GNU/Linux操作系统中,按Ctrl+Alt+F1、F2...F6等组合键可以切换到几个深色全屏终端界面,按Ctrl+Alt+F7是切换回图形界面。但是不要被它们骗了,虽然它们不是以图形界面运行,但它们实际上是一种终端仿真器。▲显示系统启动信息的虚拟控制台(图片来源:hacktolive.org,GPLv2)这些全屏终端界面与运行在GUI终端仿真器下的唯一区别在于,它们是由操作系统内核直接提供的。内核直接提供的这些终端界面称为虚拟控制台(VirtualConsole),上述运行在图形界面上的终端仿真器称为终端窗口(TerminalWindow)。除此之外没有区别。当然,因为终端窗口是运行在图形界面上的,如果图形界面崩溃了,他们也就完蛋了。这时候至少可以切换到VirtualConsole来救火,因为它们是内核直接提供的,一般只要系统本身不出问题就可以用(笑)。3.那么什么是TTY?简单来说,tty是终端的总称。为什么?看过上面2.1节的同学应该知道,最早的Unix终端是ASR-33电传打字机。Teletype/Teletypewriter的英文缩写是tty,这就是tty这个名字的来源。由于Unix被设计为多用户操作系统,因此人们会将多个终端连接到他们的计算机(在那个年代,它们都是电传打字机)。Unix系统为了支持这些电传打字机,设计了一个名为tty的子系统(是的,因为当时的终端都是tty,所以这个系统也被命名为tty,就是这么简单粗暴),具体的硬件设备抽象为位于操作系统内/dev/tty*的设备文件。为什么要将电传打字机的硬件设备抽象成“tty设备”文件呢?有兴趣的同学可以了解一下Unix操作系统中Everythingisafile的概念。▲还记得我们上面提到的特殊终端,也就是那些通过Ctrl+Alt+F1-6呼出的虚拟控制台(VirtualConsole)吗?对应上图中的tty1到tty6。随着计算机的发展,终端设备不再局限于电传打字机,但tty这个名字仍然保留了下来。久而久之,他们的概念就被混淆了。所以在现代,一个tty设备就是一个终端设备,一个终端设备就是一个tty设备,就不用区分了。由于早期计算机上的串口(SerialPort)多用于连接终端设备,所以当时的Unix也会将串口上的设备抽象为tty设备(位于/dev/ttyS*)。因此,现在人们常把串口设备称为tty设备。在tty子系统中,后来又衍生出了pty、ptmx、pts等概念,这里不再详细展开。有兴趣的同学可以参考这篇文章:LinuxTTY/PTS概述。4.Shell——提供用户界面的程序。众所周知,操作系统有一个叫做内核(Kernel)的东西,它管理着整个计算机的硬件,是现代操作系统最基本的部分。但是内核处于系统的最底层,普通用户不能随意操作,否则一不小心系统就会崩溃!但是我们总是要让用户去操作系统,怎么办呢?这就需要一个特殊的程序,接受用户输入的命令,然后帮助我们和内核进行通信,最后让内核完成我们的任务。提供用户界面的程序称为壳牌(shell)。实际上,Shell只是为用户的操作系统提供了一个入口。我们通常使用Shell来调用其他各种应用程序来实现我们的目的。比如我们想知道一个文件的内容,我们会在shell中输入命令catfoo.txt,然后shell会帮我们运行cat程序,cat会调用提供的open等系统调用由内核获取文件的内容。虽然直接与内核交互的不是Shell,但可以广义地认为Shell提供了与内核交互的用户界面。至于为什么叫Shell,看下图就知道了。是不是很像贝壳?shell一般可以分为两种类型:命令行shell和图形shell。顾名思义,前者提供命令行界面(CLI),后者提供图形用户界面(GUI)。Windows下的explorer.exe是一个典型的图形外壳(是的,它是,因为它接受你的指令,并且会帮助你与内核交互来完成你的指令)。常见的或历史上知名的命令行shell有:适用于Unix和类Unix系统:sh(Bourneshell),最经典的Unixshell;bash(Bourne-Againshell),目前大多数Linux发行版的默认shell;zsh(Zshell),我个人最喜欢的shell;fish(Friendlyinteractiveshell),一个注重易用性和友好用户体验的shell;Windows下的cmd.exe(命令提示符)和PowerShell。还有其他各种shell程序,这里就不一一列举了。如果您有兴趣,请自行搜索。:P5。shell和终端的分工现在我们知道,终端的工作就是接收用户的输入(键盘、鼠标等输入设备),丢给shell,然后将返回的结果显示出来shell给用户(例如通过监视器)。Shell的工作就是获取用户从终端输入的命令,进行解析,交给操作系统内核执行,并将执行结果返回给终端。但是,shell和终端之间的分工有些混乱。这里举个例子来说明:终端把用户的键盘输入转换成控制序列(字符以外的按键,比如左方向键→^[[D),shell解析并执行接收到的控制序列(比如^[[D→将光标向左移动);但也有例外,比如当终端接收到Ctrl+C组合键时,它不会将这个键转发给当前程序,而是发送一个SIGINT信号(默认情况下,这会导致进程终止)。其他类似的特殊组合键还有Ctrl-Z和Ctrl-\等,可以使用stty-a命令查看当前终端的设置。shell发出“改变前景色为红色(控制序列为\033[31m)”、“显示foo”等命令;终端接收这些命令并执行shell所说的操作,因此您会在终端上看到一行输出红色foo。除非重定向,否则shell永远不知道它执行的命令的输出。我们可以在终端窗口上下翻页查看过去的输出内容,这完全是终端提供的特性,与shell无关;命令提示符(Prompt)是一个完整的shell概念,与终端无关;行编辑、输入历史和自动补全功能都是shell提供的(例如shellfish有一个非常有用的历史命令和命令自动补全功能)。但是,终端也可以自己实现这些功能。比如终端仿真器XShell,可以在本地写一行命令,然后将整个命令发送到远程服务器中的Shell(在连接不好的时候有用,否则一个字都打不出来)它花费很长时间);终端中的复制粘贴功能(Shift+Insert或者鼠标右键等)基本都是终端提供的。比如Windows默认的终端对复制粘贴的支持很差,但是换一个终端(比如ConEmu)就可以很好的支持复制粘贴。但是,shell和其他命令行程序也可以提供自己的复制粘贴机制(例如vim)。6、总结计算机的历史很有意思,但是查资料太费脑子了。为了不误导他人,我在撰写这篇博文的过程中还查阅了各种文献和史料,力求内容的准确性。但是,能力有限。如果文章中还有谬误之处,欢迎在下方评论区批评指正。7.参考链接CommandLineInterface-Wikipedia“终端”、“shell”、“tty”和“控制台”之间的确切区别是什么?为什么虚拟终端是“虚拟的”,“真实”终端是什么/为什么/在哪里?终端、shell、“tty”和控制台之间有什么区别?-知乎,你真的知道终端是什么吗?-Linux大神博客终端-WikipediaTerminal模拟器-Wikipediaconsole(4):consoleterminal/virtualconsole-LinuxmanpageLinuxTTY/PTSOverview-SegmentFaultLinuxTTYframework(1)_基本概念Shell(computing)-维基百科学习bashshell-鸟哥Linux私房菜Ubuntu联机帮助页:控制终端代码-Linux控制终端转义和控制序列