Command line crash course

在您的开发过程中,您无疑需要在终端上运行一些命令(或者在“命令行”上,它们实际上是相同的)。本文介绍了终端、需要输入的基本命令、如何将命令链接在一起,以及如何添加自己的命令行接口(CLI)工具。

先决条件: 熟悉核心的 HTML, CSS, 和 JavaScript 语言。
目标: 要了解什么是终端/命令行,应该学习什么基本命令,以及如何安装新的命令行工具。

欢迎使用终端

终端是一个文本界面,用于执行基于文本的程序。如果您正在运行任何用于web开发的工具,那么几乎可以保证您必须打开命令行并运行一些命令来使用您所选择的工具(您经常会看到这样的工具被称为CLI工具命令行接口工具)。

大量的工具可以通过在命令行中输入命令来使用;许多是预先安装在您的系统上的,还有大量其他的可以从包注册表中安装。包注册表类似于应用程序商店,但(主要)用于基于命令行的工具和软件。我们将在本章后面看到如何安装一些工具,在下一章我们将学习更多关于包注册表的知识。

对命令行最大的一个批评是它在用户体验方面非常缺乏。第一次查看命令行可能是一种令人畏惧的体验:空白屏幕和闪烁的光标,对于要做什么几乎没有明显的帮助。

表面上看,它们并不受欢迎,但您可以使用它们做很多事情,我们保证,通过一些指导和练习,使用它们会变得更容易!这就是为什么我们提供这一章来帮助你在这个看似不友好的环境中开始。

终端从何而来?

终端机起源于20世纪五六十年代,它最初的形式与我们今天使用的并不相似(这是我们应该感谢的)。你可以在维基百科的词条中读到一些历史 Computer Terminal

从那时起,终端一直是所有操作系统的一个不变的特征,从台式电脑到隐藏在云中的服务器(它并不是真正的云),到像树莓PI Zero这样的微型计算机,甚至到移动电话。它提供了对计算机底层文件系统和底层特性的直接访问,因此,如果您知道自己在做什么,它对于快速执行复杂任务非常有用。

例如,编写一个命令来立即更新数百个文件的标题,例如从ch01-xxxx.png更新到ch02-xxxx.png,这对于自动化也很有用。如果您使用finder或explorer GUI应用程序更新文件名,这将花费您很长时间。

总而言之,终端不会很快消失。

终端像什么呢?

下面你可以看到一些不同口味的程序,你可以得到一个终端。

下面的图片显示了Windows中可用的命令提示,有很多种选项,从“cmd”程序到“powershell”,可以在开始菜单中输入程序名称运行。

A vanilla windows cmd line window, and a windows powershell window

下面是macOS终端应用程序。

A basic vanilla mac terminal

你如何进入终端?

现在许多开发人员都在使用基于unix的工具(例如,终端,以及你可以通过它访问的工具)。目前web上存在的许多教程和工具都支持(可悲的是假定)基于unix的系统,但不用担心它们在大多数系统上都可用。在本节中,我们将了解如何访问所选系统上的终端。

Linux/Unix

如上所述,Linux / Unix系统默认情况下在应用程序中列出了一个可用的终端。

macOS

macOS有一个名为Darwin的系统,它位于图形用户界面的下方。Darwin是类unix系统,它提供了终端和对底层工具的访问。macOS Darwin在很大程度上与Unix不相上下,当然在阅读本文时不会给我们带来任何担忧。

终端可在macOS的“应用程序/实用程序/终端”上使用。

Windows

与其他一些编程工具一样,在Windows上使用终端(或命令行)传统上并不像在其他操作系统上那样简单。但情况正在好转。

很长一段时间以来,Windows一直有自己的名为cmd(命令提示符)的类似于终端的程序,但这显然与Unix命令不同,它相当于老式的Windows DOS提示符。

然而,在现代,Windows的最佳选择是Windows Linux子系统(WSL),它是一个兼容层,用于从Windows 10中直接运行Linux操作系统,允许您直接在Windows上运行真正的终端,而不需要虚拟机。

a screenshot of the windows subsystem for linux documentation

至于在Windows上选择什么选项,我们强烈建议尝试安装WSL。您可以坚持使用默认的命令提示符(cmd),许多工具都可以正常工作,但是您会发现,如果与Unix工具具有更好的一致性,那么一切都会变得更容易。

边注:命令行和终端的区别是什么?

通常你会发现这两个术语可以互换使用。从技术上讲,终端是启动并连接到shell的软件。shell是您的会话和会话环境(提示符和快捷方式等内容可以在其中定制)。命令行是您输入命令并且光标闪烁的文字行。

必须使用终端吗

尽管命令行提供了大量的工具,但是如果您使用的工具是这样像 Visual Studio Code

还有大量的扩展可以作为代理使用终端命令,而不需要直接使用终端。但是,您不会找到一个代码编辑器扩展来满足您想要做的所有事情 — 你最终将会获得一些使用终端的经验。

基本的内置终端命令

说的够多了,让我们开始看看一些终端命令吧!下面是命令行可以做的一些事情,以及每种情况下相关工具的名称

  • 导航计算机的文件系统以及基本级别的任务,如创建、复制、重命名和删除:

    • 移动您的目录结构 : cd

    • 建立目录: mkdir
    • 创建文件(修改他们的原数据): touch
    • 复制文件: cp
    • 移动文件: mv
    • 删除文件或目录: rm
  • 下载在特定的url找到的文件: curl
  • 在较大的文件体中寻找特定的片段: grep
  • 主页查看文件的内容: less, cat
  • 操作和转换文本流(例如,讲HTML文件中<div>的所有实例改为<article>): awk, tr, sed

注意:在web上有许多很好的教程深入了解web上的命令行——这只是一个简短的介绍

让我们继续,看看在命令行上使用这些工具中的几个。在进一步操作之前,先打开终端程序

在命令行中导航

当您访问命令行时,您将不可避免地需要导航到一个特定的目录“做一些事情”。所有的操作系统(假设是默认设置)都将在您的“home”目录中启动它们的终端程序,从那里您可能想要移动到另一个地方。

 cd 命令允许您更改目录。从技术上讲,cd不是一个程序,而是内置的。这意味着您的操作系统可以开箱即用地提供它,而且您也不会意外地删除它,感谢上帝!您不需要过多地担心某个命令是否是内置的,但是要记住,内置的命令会在所有基于unix的系统上出现。

要更改目录,请在终端中键入cd,然后输入要移动到的目录。假设该目录在您的主目录中,您可以使用 cd Desktop (请参见下面的屏幕截图).

results of the cd Desktop command being run in a variety of windows terminals - the terminal location moves into the desktop

试着把这个输入到你的系统终端

cd Desktop

如果您想回到上一个目录,您可以使用两个点

cd ..

注意:一个非常有用的终端快捷方式是使用tab 键自动完成你知道的名字,而不是必须键入整个东西。例如,在键入以上两个命令后,尝试键入 cd D 并按下tab — 它应该自动完成目录名称 Desktop 对于您,只要它存在于当前目录中。在你前进的过程中记住这一点。

如果要转到的目录嵌套得很深,则需要知道访问该目录的路径。 当您更加熟悉文件系统的结构时,这通常会变得更容易,但是如果您不确定路径,通常可以使用ls命令(请参见下文)的组合并在其中单击来确定它的路径。 “资源管理器/查找器”窗口可查看目录相对于当前位置的位置。

例如,如果您想进入一个名为src的目录,该目录位于桌面的一个名为project的目录中,您可以从您的主文件夹键入这三个命令来到达该目录

cd Desktop
cd project
cd src

但这只是浪费时间,相反,您可以键入一个命令,用斜杠分隔路径中的不同项,就像在CSS、HTML或JavaScript代码中指定图像或其他资产的路径一样

cd Desktop/project/src

例如,请注意,在路径上包含一个前斜线将使路径成为绝对路径 /Users/your-user-name/Desktop. 像我们上面做的那样,省略前导斜杠可以使路径相对于当前的工作目录。这与您在web浏览器中看到的url完全相同。前面的斜杠意味着“在网站的根”,而省略斜杠意味着“这个URL是相对于我当前页面的”。

注意:在windows中,你使用反斜杠而不是正斜杠。cd Desktop\project\src — 他的可能看起来很奇怪,但是如果你感兴趣的话, watch this YouTube clip 微软的一位主要工程师对此进行了解释。

列出目录内容

另一个内置的Unix命令是ls (list的缩写),它列出当前所在目录的内容。注意,这不会工作,如果你使用默认的Windows命令提示符(cmd),相当于dir。

现在试着在终端上运行它

ls

这提供了当前工作目录中的文件和目录的列表,但这些信息实际上很基本,您只能得到每个项的名称,而不能知道它是文件还是目录,或者其他任何东西。幸运的是,对命令的用法进行一个小小的更改就可以提供更多的信息。

介绍命令选项

大多数终端命令都有选项,这些选项是您添加到命令末尾的修饰符,它们使命令的行为略有不同。它们通常由命令名后的空格、后接破折号、后接一个或多个字母组成。

例如,试一试看,你能得到什么?

ls -l 

至于 ls, the -l 选项为您提供每行一个文件或目录的清单,并显示更多信息。可以通过查找行最左边的字母“d”来识别目录。这些是我们可以做到的 cd 进入.

下面是一个屏幕截图,顶部是一个普通的macOS终端,还有一个定制的终端,添加了一些额外的图标和颜色,让它看起来生动,都显示了运行的结果ls -l:

A vanilla mac terminal and a more colorful custom mac terminal, showing a file listing - the result of running the ls -l command

注意:要确切地了解每个命令有哪些可用选项,您可以查看它man page. 通过键入 man 命令,后跟要查找的命令的名称,例如man ls. 这将在终端的默认文本文件查看器中打开手册页(例如, less(在我的终端中),然后您应该能够使用箭头键或其他类似的机制在页面中滚动。手册页详细地列出了所有选项,一开始可能有点吓人,但至少在需要时您知道它就在那里。一旦您完成了对手册页的查看,您需要使用文本查看器的quit命令退出它("q" 在 less;如果不明显,你可能需要在网上搜索才能找到).

注意:

要同时运行具有多个选项的命令,通常可以将它们全部放在破折号后面的单个字符串中ls -lah, 或ls -ltrh.尝试在 ls 了解这些额外选项的作用

既然我们已经讨论了两个基本命令,那么稍微浏览一下您的目录,看看是否可以从一个位置导航到下一个位置。

创建,复制,移动,删除

在使用终端时,您可能会经常使用其他一些基本实用程序命令。它们非常简单,所以我们不会像前一对那样详细地解释它们。

在您创建的某个地方的测试目录中使用它们,这样您就不会意外地删除任何重要的内容,使用下面的示例命令作为指导

  • mkdir —这将在您所在的当前目录中创建一个新目录,名称是您在命令名之后提供的。例如mkdir my-awesome-website将创建一个新目录叫my-awesome-website.
  • rmdir —删除指定目录,但仅当它为空时。例如rmdir my-awesome-website

    将删除我们在上面创建的目录。如果您希望删除一个非空的目录(并删除其中包含的所有内容),则可以使用-r 选项(递归),但这很危险。 确保以后在目录中不需要任何内容​​,因为它将永远消失。

  • touch —在当前目录中创建一个新的空文件。例如touch mdn-example.md 创建一个新的空文件叫做 mdn-example.md.
  • mv

    例如,将文件从第一个指定的文件位置移动到第二个指定的文件位置mdn-example.md mdn-example.txt(这些位置被写成文件路径)。此命令移动一个名为mdn-example.md在当前目录中调用一个文件mdn-example.txt in the current directory.从技术上讲,文件正在被移动,但是从实际的角度来看,这个命令实际上是在重命名文件。

  • cp — 类似于 mv, cp在指定的第一个位置和第二个位置创建文件的副本。例如
    , cp mdn-example.txt mdn-example.txt.bak创建一个副本mdn-example.txt 叫做 mdn-example.txt.bak(当然,如果你愿意,你也可以叫它别的名字)。
  • rm —删除指定的文件。例如, rm mdn-example.txt 删除单个文件叫做 mdn-example.txt.请注意,此删除是永久性的,不能通过桌面用户界面上的回收站撤消。

注意: 许多终端命令允许您使用星号作为“通配符”字符,意思是“任何字符序列”。这允许您一次对可能大量的文件运行操作,所有这些文件都匹配指定的模式。作为一个例子, rm mdn-* 将删除所有文件开头mdn-. rm mdn-*.bak 会删除所有文件的开头mdn- 结束 .bak.

考虑终端有害吗?

我们之前提到过这一点,但为了明确起见,您需要小心使用终端。简单的命令不会带来太多危险,但是当您开始将更复杂的命令组合在一起时,您需要仔细考虑该命令将执行什么操作,并在最终在指定的目录中运行它们之前先尝试测试它们。

假设您在一个目录中有1000个文本文件,您想遍历它们,并且只删除文件名中有特定子字符串的文件。如果不小心,可能会删除一些重要的内容,在此过程中丢失大量工作。

要养成的一个好习惯是在文本编辑器中编写您的terminal命令,弄清楚您认为它应该是什么样子,然后对目录进行备份,并首先尝试在该备份上运行命令,以测试它。

另一个好建议是,如果你不习惯在自己的机器上尝试终端命令,可以在Glitch.com上试试。除了是测试web开发代码的好地方外,这些项目还允许您访问终端,这样您就可以直接在该终端中运行所有这些命令,而且不会破坏您自己的机器。

a double screenshot showing the glitch.com home page, and the glitch terminal emulator

快速浏览特定终端命令的一个很好的资源是 tldr.sh. 这是一个社区驱动的文档服务,类似于MDN,但特定于终端命令。

在下一节中,让我们更进一步(实际上是几个层次),看看如何在命令行上将工具连接在一起,从而真正了解终端如何优于常规的桌面用户界面。

与管道命令连接在一起

当您开始使用。将命令链接在一起时,终端才真正成为自己的终端 | (pipe) 的象征。让我们看一个简单的例子来说明这意味着什么。

我们已经看了 ls, 它可以输出文件目录:

ls

但是如果我们想要快速计算当前目录中的文件和目录的数量会怎样呢ls 不能单独运行

还有另一个可用的Unix工具,称为wc. 它计算输入到其中的单词、行、字符或字节的数量。这可以是一个文本文件,下面的示例输出其中的行数

myfile.txt:

wc -l myfile.txt

但是它还可以计算输入到它的输出的行数。例如,下面的命令计算ls命令输出的行数(如果单独运行,它通常会打印到终端),并计算到终端的输出

ls | wc -l

因为ls 在自己的行上打印每个文件或目录,这有效地为我们提供了目录和文件计数。

这是怎么回事?(unix)命令行工具的一般原理是,它们将文本打印到终端(也称为“打印到标准输出”或STDOUT). 很多命令也可以从流输入(称为“标准输入”o)中读取内容 STDIN).

管道操作符可以将这些输入和输出连接在一起,允许我们构建越来越复杂的操作,以满足我们的需要。一个命令的输出可以成为下一个命令的输入。在这种情况下, ls 通常会将其输出到STDOUT, 但是相反 ls输出被制成wc, 它将该输出作为输入,计算它包含的行数,然后将该计数输出到STDOUT。

一个稍微复杂一点的例子

因此,如果您使用curl请求https://developer.mozilla.org/docs/Web/API/fetch,则不会得到输出。 现在就试试:

curl https://developer.mozilla.org/en-US/docs/Web/API/fetch

我们想精确的告诉 curl 遵循重定向使用-L 标签.

让我们也看看标题 developer.mozilla.org 返回使用 curl's -I 标签, 并打印它发送到终端的所有位置重定向,通过管道输出 curl 到grep (我们将要求grep返回包含单词“location”的所有行)。

尝试运行以下代码,您将看到在到达最终页面之前,实际上发生了三次重定向

curl https://developer.mozilla.org/docs/Web/API/fetch -L -I | grep location

输出应该是这样的 (curl 首先会输出一些下载计数器之类的东西):

location: /en-US/docs/Web/API/fetch
location: /en-US/docs/Web/API/GlobalFetch/GlobalFetch.fetch()
location: /en-US/docs/Web/API/GlobalFetch/fetch
location: /en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

尽管有些做作,我们可以把这个结果做得更深入一点,并变换 location: 行内容,将基本的起点添加到每个起点的开始,这样我们就可以打印出完整的url。为此,我们将在混合中添加awk(它是一种类似于JavaScript、Ruby或Python的编程语言,只是要老得多!)

尝试运行这个:

curl https://developer.mozilla.org/docs/Web/API/fetch -L -I | grep location | awk '{ print "https://developer.mozilla.org" $2 }'

最终的输出应该是这样的

https://developer.mozilla.org/en-US/docs/Web/API/fetch
https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/GlobalFetch.fetch()
https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

通过组合这些命令,我们定制了输出以显示完整的url,当我们请求时,Mozilla服务器将通过这些url重定向/docs/Web/API/fetch URL.了解您的系统将在未来几年证明是有用的,您将了解这些单一服务工具是如何工作的,以及它们如何成为您解决小众问题的工具库的一部分。

添加工具

现在我们已经了解了系统自带的一些内置命令,让我们看看如何安装和使用第三方CLI工具。

目前,用于前端web开发的可安装工具的巨大生态系统主要存在于内部 npm, 与Node.js紧密合作的私有的包托管服务。随着时间的推移,您可以期望看到更多的包提供者。

Installing Node.js 还要安装npm命令行工具(以及一个以npm为中心的补充工具npx),它提供了安装其他命令行工具的网关。js和npm在所有系统上都能工作:macOS、Windows和Linux。

现在在您的系统上安装npm,转到上面的URL,下载并运行适合您的操作系统的Node.js安装程序。如果出现提示,请确保将npm作为安装的一部分。

the node.js installer on windows, showing the option to include npm

尽管我们将在下一篇文章中讨论许多不同的工具,但我们将继续深入研究 Prettier. Prettier是一种固执己见的代码格式化程序,它只有“很少的选择”。更少的选择往往意味着更简单。考虑到工具在复杂性方面有时会失控,“很少的选项”可能非常有吸引力。

在哪里下载我们的CLI工具?

在开始安装Prettier之前,有一个问题需要回答:“我们应该安装到哪里?

npm 我们可以选择在全球安装工具,因此我们可以在任何地方或本地访问当前项目目录。

每种方式各有利弊 — 而这张全球安装的利弊清单还远远不够详尽:

全球安装的优点

全球安装的缺点

任何地方在您的终端

可能与您项目的代码库不兼容
只下载一次

您团队中的其他开发人员无法使用这些工具,例如,如果您通过git这样的工具共享代码基。

使用较少的磁盘空间

与前一点相关的是,它使得项目代码更难复制(如果您在本地安装工具,可以将它们设置为依赖项并使用npm进行安装npm install).

总是相同的版本

感觉像任何其他unix命令

尽管缺点清单比较短,但是全局安装的负面影响可能要比好处大得多。然而,现在我们宁可追求简单,而采用全局安装来保持简单。在下一篇文章中,我们将进一步了解本地安装以及它们的优点。

下载 Prettier

对于本文,我们将安装Prettier作为全局命令行实用程序。

Prettier是一款专门为前端开发人员设计的代码格式化工具,专注于基于javascript的语言,并增加了对HTML、CSS、SCSS、JSON等的支持。Prettier 能:

  • 省去了在所有代码文件中手动保持样式一致的认知开销;Prettier可以自动为您完成此操作。
  • 帮助Web新手以最佳方式完成他们的代码.
  • 安装在任何操作系统上,甚至直接作为项目工具的一部分,以确保从事您的代码工作的同事和朋友使用您正在使用的代码风格。
  • 配置为在保存时运行、在键入时运行,甚至在发布代码之前运行(使用稍后将在模块中看到的其他工具)。

安装node之后,打开终端并运行以下命令来安装更漂亮的程序:

npm install --global prettier

命令运行完成后,Prettier工具现在可以在终端中的文件系统中的任何位置使用。

与许多其他命令一样,不带任何参数运行该命令将提供用法和帮助信息。现在试试这个

prettier

输出应该是这样的

Usage: prettier [options] [file/glob ...]

By default, output is written to stdout.
Stdin is read if it is piped to Prettier and no files are given.

…

即使它很长,至少浏览一下使用信息也是值得的。它将帮助您更好地理解如何使用该工具。

尝试 Prettier

让我们快速演示一下Prettier,这样您就可以看到它是如何工作的。

首先,在文件系统中容易找到的地方创建一个新目录。可能是一个叫做prettier-test 在你的 Desktop.

现在将以下代码保存在一个名为index.js, 在测试目录中:

const myObj = {
a:1,b:{c:2}}
function printMe(obj){console.log(obj.b.c)}
printMe(myObj)

我们可以在代码基上运行得更好,以检查我们的代码是否需要调整。cd到您的目录中,并尝试运行此命令:

prettier --check index.js

你的产出应该是:

Checking formatting...
index.js
Code style issues found in the above file(s). Forgot to run Prettier?

有些代码样式是可以修改的。没有问题。添加 --write option to the prettier命令将修复这些问题,让我们专注于实际编写有用的代码。

现在尝试运行这个版本的命令:

prettier --write index.js

你可能得到这样的输出:

Checking formatting...
index.js
Code style issues fixed in the above file(s).

但更重要的是,如果你回头看你的JavaScript文件,你会发现它被重新格式化成这样:

const myObj = {
  a: 1,
  b: { c: 2 },
};
function printMe(obj) {
  console.log(obj.b.c);
}
printMe(myObj);

根据您的工作流(或您选择的工作流),您可以将其作为流程的自动化部分。自动化确实是工具的优势所在;我们的个人偏好是那种无需配置任何东西就能“自动发生”的自动化。

使用Prettier有许多实现自动化的方法,尽管它们超出了本文的范围,但是有一些很好的在线资源可以提供帮助(已经链接到其中一些)。您可以调用更漂亮的:

  • 在将代码提交到git存储库之前,使用Husky.

  • 作为持续集成检查的一部分,可以使用以下工具Github Actions.

我们个人的偏好是第二个当使用say VS代码时,Prettier会启动并清理每次我们点击保存时需要做的格式化。关于以不同方式使用Prettier,您可以在 Prettier docs.

尝试其他的工具

如果你想尝试更多的工具,这里有一个简短的列表,很有趣的尝试:

  • bat — 一个更好的 cat (cat 用于打印文件内容)。
  • prettypingping在命令行上,但是是可视化的(ping是检查服务器是否有响应的有用工具)。
  • htop —进程查看器,当某些东西使您的CPU风扇的行为像一个喷气发动机,并且您想要识别出错的程序时,它非常有用。
  • tldr —在本章前面提到的,但是可以作为命令行工具使用。

注意,上面的一些建议可能需要使用npm进行安装,就像我们使用Prettier所做的那样。

总结

这使我们结束了对终端/命令行的简短浏览。 接下来,我们将更详细地介绍软件包管理器,以及如何使用它们。

In this module