type
Post
status
Published
date
May 9, 2023
slug
summary
tags
命令行
category
技术基本功
icon
password
Property
May 14, 2023 10:20 PM
🤔 命令行是什么?控制台、终端、命令行(CLI)和 shell 之间的区别控制台终端Shell命令行(CLI)小结为什么要学习使用命令行?有哪些不同的 Shell ?一点历史——Posix怎么知道我在运行哪个 shell哪个 shell 更好最常用且最有用的命令学会编写简单的 Shell 脚本
🤔 命令行是什么?
命令行(Command Line),也称为命令行界面(Command Line Interface,简称 CLI),是计算机操作系统提供的一种基于文本的用户界面,用于向计算机发送命令和指示。通过命令行,用户可以直接输入指令并获取相应的输出,无需通过图形用户界面(Graphical User Interface,简称 GUI)进行交互操作。
在命令行中,用户通过输入命令和参数来执行计算机上的各种操作,例如打开文件、移动文件、创建文件夹、编译程序等。命令行通常使用纯文本格式,命令和参数之间使用空格或其他分隔符进行区分。
命令行对于开发人员和系统管理员来说非常重要,因为它可以方便地进行批处理、自动化任务和管理服务器等工作。在 Unix 和 Linux 系统中,命令行是非常重要的界面,许多工具和应用程序都是基于命令行实现的。在 Windows 系统中,命令行也是一种重要的工具,可以用来执行一些高级任务和管理系统。
控制台、终端、命令行(CLI)和 shell 之间的区别
我认为一个好的开始是准确了解什么是命令行。
在提到这一点时,你可能听说过终端、控制台、命令行、CLI 和 shell 这些术语。人们经常交替使用这些词,但事实是它们实际上是不同的东西。
区分它们并不一定是很重要的知识,但它将有助于澄清事情。因此,让我们简单地解释一下每一个。
控制台
控制台(console)是允许你与计算机互动的物理设备。
通俗地说,它就是你的电脑屏幕、键盘和鼠标。作为一个用户,你通过控制台与计算机进行互动。
终端
终端是一个文本输入和输出环境。它是作为一个包装器(wrapper) 的程序,允许我们输入计算机处理的命令。
用简单来说,它是一个“窗口”,你在其中输入计算机将处理的实际命令。
请记住,终端是一个程序,就像其他任何程序一样。和其他程序一样,你可以随意安装和卸载它。也可以在你的电脑中安装许多终端,随时运行你想运行的终端。
所有的操作系统都安装了一个默认的终端,但有很多选择,每个都有自己的功能和特点。
Shell
Shell 是一个程序,作为命令行解释器。它处理命令并输出结果。它解释和处理用户输入的命令。
与终端(terminal)一样,shell 是所有操作系统中默认的程序,但也可以由用户自己安装和卸载。
不同的 shell 也有不同的语法和特点。也可以在你的电脑上安装许多 shell,并在你想的时候运行每个 shell。
在大多数 Linux 和 Mac 操作系统中,默认的 shell 是 Bash。而在 Windows 中则是 Powershell。其他一些常见的 shell 的例子是 Zsh 和 Fish。
shells 也可以作为编程语言来工作,在这个意义上,我们可以用它们建立脚本(scripts),使我们的计算机执行某种任务。脚本只不过是一系列指令(命令),我们可以将其保存在文件中,然后在我们想执行的时候执行。
我们将在本文的后面看一下脚本的内容。现在只要记住,shell 是你的计算机用来理解和执行你的命令的程序,你也可以用它来编写任务。
还要记住,终端是 shell 运行的程序。但这两个程序是独立的。这意味着,我可以让任何 shell 在任何终端上运行。在这个意义上,两个程序之间没有依赖性。
命令行(CLI)
CLI 是一个界面,我们在其中输入命令供计算机处理。用简单来说,它是一个空间,你在其中输入计算机将处理的命令。
这实际上与终端(terminal)是一样的,在我看来,这些术语可以互换使用。
这里要提到的一件有趣的事情是,大多数操作系统都有两种不同类型的界面:
- CLI,它将命令作为输入,以使计算机执行任务。
- 另一个是 GUI(图形用户界面),用户可以看到屏幕上的东西并点击它们,计算机将通过执行相应的任务对这些事件作出反应。
小结
- 控制台是一个物理设备,允许你跟计算机进行交互。这在过去很多人共用一台主机时比较常见。对于现在的个人电脑来说,控制台和主机是一体的。对于远程操控云服务器来说,此时你的个人电脑就是云服务器的控制台。
- 终端是一个文本输入和输出环境,终端里可以运行各种各样的 Shell 。
- Shell 是一个命令解释器,它处理命令并输出结果。
- CLI 命令行界面和 GUI 图形界面是相对应的,都是软件前端的一种形式。因为控制台、终端和 Shell 大多以运行命令行界面为主所以这些也常常被叫做 CLI。
为什么要学习使用命令行?
我们刚刚提到,大多数操作系统都有一个图形用户界面。因此,如果我们可以在屏幕上看到东西,并点击来做我们想做的事情,你可能会想,为什么你要学习这个复杂的终端(terminal)/cli/shell 呢?
第一个原因是,对于许多任务来说,它只是更有效率。我们稍后会看到一些例子,但是有很多任务在 GUI 中需要在不同的窗口中进行多次点击。但在 CLI 上,这些任务可以用一个命令来执行。
从这个意义上说,熟悉命令行将帮助你节省时间,能够更快地执行你的任务。
第二个原因是,通过使用命令,你可以轻松地自动化任务。如前所述,我们可以用我们的 shell 建立脚本,然后在我们想要的时候执行这些脚本。在处理那些我们不想重复做的重复性任务时,这非常有用。
仅举一些例子,我们可以建立一个脚本,为我们创建一个新的在线 repo,或者为我们在云服务商上创建一个特定的基础设施,或者执行一个更简单的任务,如每小时改变我们的屏幕墙纸。
脚本是一种节省重复性任务时间的好方法。
第三个原因是,有时 CLI 将是我们能够与计算机互动的唯一方式。例如,当你需要与云平台服务器互动时。在大多数情况下,你不会有一个 GUI,只有一个 CLI 来运行命令。
因此,熟练掌握 CLI 将使你能够在所有情况下与计算机互动。
最后一个原因是它看起来很酷、很有趣。你不会看到电影中的黑客在他们的电脑上点击,对吗?
有哪些不同的 Shell ?
在深入研究你可以在终端运行的实际命令之前,我认为认识不同类型的 shell 以及如何识别你目前正在运行的 shell 很重要。
不同的 shell 有不同的语法和功能,所以要知道到底要输入什么命令,你首先要知道你在运行什么 shell。
一点历史——Posix
对于 shells,有一个通用的标准,叫作 Posix。
Posix 之于 shell 与 ECMAScript 之于 JavaScript 非常相似。它是一个标准,规定了所有 shell 应该遵守的某些特性和功能。
这个标准是在 20 世纪 80 年代建立的,目前大多数 shell 都是根据这个标准开发的。这就是为什么大多数 shell 共享类似的语法和类似的特征。
怎么知道我在运行哪个 shell
要知道你当前运行的是什么 shell,只需打开你的终端并输入
echo $0
。这将打印出当前运行的程序名称,在这种情况下,它就是实际的 shell。哪个 shell 更好
大多数 shell 之间没有很大的区别。由于它们大多符合相同的标准,你会发现它们中的大多数工作都是类似的。
不过,你可能想知道一些细微的差别:
- 如前所述,Bash 是使用最广泛的,在 Mac 和 Linux 上默认安装。
- Zsh与 Bash 非常相似,但它是在 Bash 之后创建的,并且比它有一些不错的改进。如果你想更详细地了解它的区别,这里有一篇很酷的文章是关于 zsh 的。
- Fish 是另一个常用的 shell,它有一些不错的内置功能和配置,如自动完成和语法高亮。关于 Fish 的问题是,它不是 Posix 兼容,而 Bash 和 Zsh 是。这意味着你能在 Bash 和 Zsh 上运行的一些命令不能在 Fish 上运行,反之亦然。这使得 Fish 脚本与 Bash 和 Zsh 相比对大多数计算机的兼容性较差。
- 还有一些其他的 shell,比如 Ash 或 Dash(命名只是让一切变得更加混乱,我知道......),它们是 Posix shell 的精简版本。这意味着它们只提供 Posix 所需要的功能,而没有其他的。而 Bash 和 Zsh 增加了比 Posix 要求更多的功能。
事实上,shells 增加了更多的功能,使它们更容易、更友好地进行交互,但执行脚本和命令的速度较慢。
因此,一种常见的做法是使用 Bash 或 Zsh 这样的 增强型 shell 进行一般的交互,而使用 Ash 或 Dash 这样的剥离型 shell 来执行脚本。
当我们在后面讨论脚本时,我们将看到如何定义什么 shell 来执行一个给定的脚本。
如果你对这些 shell 之间更详细的比较感兴趣,这里有一个视频,解释得非常清楚。
如果必须推荐一个 shell,我会推荐 bash,因为它是最标准和最常用的一个。这意味着你能够将你的知识转化为大多数环境。
但是,事实上,大多数 shell 之间并没有很大的区别。所以在任何情况下,你都可以尝试几种,看看你最喜欢哪一种。:)
最常用且最有用的命令
现在我们对 CLI 的工作方式有了一个基础,让我们深入了解一下最有用的命令,你可以开始在你的日常工作中使用。
请记住,这些例子将基于我目前的配置(Linux 操作系统上的 Bash)。但无论如何,大多数命令应该适用于大多数配置。
- Echo 在终端打印出我们传递给它的任何参数。
echo Hello freeCodeCamp! // Output: Hello freeCodeCamp!
- pwd 代表打印工作目录,它打印出我们目前在计算机中的位置或目录。
pwd // Output: /home/German
- ls 向你展示你当前所在的目录的内容。它将向你展示你当前目录中的文件和其他目录。
ls // Output: node_modules package.json package-lock.json public README.md src
- 如果你将此命令传递给标志或参数
-a
,它还将向您显示隐藏的文件或目录,像.git
or.gitignore
文件。
ls -a // Output: . .env .gitignore package.json public src .. .git node_modules package-lock.json README.md
- cd 是 Change directory 的缩写,它将把你从你的当前目录带到另一个目录。
在我的
home
目录下,我可以输入cd Desktop
,它将把我带到桌面目录。如果我想上升一个目录,也就是说,去包含当前目录的目录,我可以输入
cd ..
。如果你只输入
cd
,它将直接带你到你的 home
目录。- mkdir 代表制作目录,它将为你创建一个新的目录。你必须把目录名称参数传给命令。
如果我想创建一个名为 "Test "的新目录,我将输入
mkdir test
。- rmdir 代表删除目录,它就是这样做的。它和
mkdir
一样需要目录名参数:rmdir test
。
- touch 允许你在当前目录下创建一个空文件。作为参数,它需要文件名,如
touch test.txt
。
- rm 允许你删除文件,与
rmdir
允许你删除目录的方式相同。rm test.txt
- cp 允许你复制文件或目录。这个命令需要两个参数:第一个是你想复制的文件或目录,第二个是你复制的目的地(你想把文件/目录复制到哪里)。
如果我想在同一目录下复制我的 txt 文件,我可以输入以下内容:
cp test.txt testCopy.txt
看,目录没有改变,因为在目的地中我输入了新的文件名。
如果我想把文件复制到一个不同的目录,但保持相同的文件名,我可以输入这个:
cp test.txt ./testFolder/
而如果我想复制到一个不同的文件夹,改变字段名,当然可以这样输入:
cp test.txt ./testFolder/testCopy.txt
- mv 是移动的简称,它让我们把一个文件或目录从一个地方移动到另一个地方。也就是说,在一个新的目录中创建它,并在前一个目录中删除它(就像你通过剪切和粘贴所做的一样)。
同样,这个命令需要两个参数,即我们想要移动的文件或目录和目的地。
mv test.txt ./testFolder/
如果我们愿意,也可以在同一命令中改变文件的名称:
mv test.txt ./testFolder/testCopy.txt
- head 允许你直接从终端查看文件或管道数据的开始部分。
head test.txt // Output: this is the beginning of my test file
- tail 的工作原理是一样的,但它会向你显示文件的结尾部分内容。
tail test.txt // Output: this is the end of my test file
- --help/ 标志可用于大多数命令,它将返回如何使用该命令的信息。
cd --help // output: cd: cd [-L|[-P [-e]] [-@]] [dir] Change the shell working directory.
- 以类似的方式,man 命令将返回任何特定命令的信息。
- code 将打开你的默认代码编辑器。如果你单独输入这个命令,它只是打开你最近打开的文件/目录的编辑器。
你也可以通过传递参数来打开一个指定的文件:
code test.txt
。或者通过传递新的文件名来打开一个新的文件:
code thisIsAJsFile.js
.- edit 将在你的默认命令行文本编辑器上打开文本文件(如果你是在 Mac 或 Linux 上,可能是 Nano 或 Vim)。
- Ctrl+c 允许你退出终端正在运行的当前进程。例如,如果你正在用
npx create-react-app
创建一个 react 应用,并想在某个时候取消构建,只要按下组合键 ctrl+c,它就会停止。
- 从终端复制文本可以用 ctrl+shift+c 来完成,粘贴可以用 ctrl+shift+v 来完成。
- clear 将清除你的终端上的所有内容。
- exit 将关闭你的终端,(这不是一个命令,但它也很酷)ctrl+alt+t 将为你打开一个新终端。
- 通过按上、下方向键你可以浏览你之前输入的命令。
- 按下 tab,你将得到基于你到目前为止所写的命令的自动补全。按下两次tab,你会得到基于你到目前为止所写命令的建议。
学会编写简单的 Shell 脚本
现在我们准备进入命令行中真正有趣和很棒的部分,即脚本!
正如我之前提到的,一个脚本只不过是一系列我们可以在任何时候执行的命令或指令。为了解释我们如何编写一个脚本,我们将使用一个简单的例子,让我们通过运行一个命令来创建一个 github repo。 ;)
- 首先要做的是创建一个
.sh
文件。你可以把它放在任何地方。我把我的文件称为newGhRepo.sh
。
- 然后在你选择的文本/代码编辑器中打开它。
- 在我们的第一行,我们将写下以下内容
#! /bin/sh
。
这被称为 shebang,它的作用是声明什么 shell 来运行这个脚本。
还记得我们以前提到过,我们可以用一个给定的 shell 来进行一般的交互,而用另一个给定的 shell 来执行一个脚本吗?那么,shebang 就是决定由哪个 shell 来运行脚本的指令。
如前所述,我们使用一个精简的 shell(也称为 sh shells)来运行脚本,因为它们更有效率(尽管说实话,这种差别可能是难以察觉的,这只是一种个人偏好)。在我的电脑中,我把 dash 作为我的 sh shell。
如果我们想让这个脚本用 bash 运行,那么 shebang 应该是
#! /bin/bash
。我们的下一行将是
repoName=$1
。这里我们声明了一个名为 repoName 的变量,并将其分配给脚本收到的第一个参数的值。
一个参数是一组在脚本/命令后面输入的字符。就像
cd
命令一样,我们需要指定一个目录参数,以便改变目录(即:cd testFolder
)。我们可以通过使用
$
符号和预期参数的顺序来识别脚本中的参数。如果我期望有一个以上的参数,我可以这样写:
paramOne=$1 paramTwo=$2 paramThree=$3 ...
所以,我们希望将代码库的名称作为我们脚本的参数。但如果用户忘记输入会怎样?我们需要想一下,所以接下来我们要编写一个条件,不断要求用户输入版本库名称,直到收到该参数。
我们可以这样做:
while [ -z "$repoName" ] do echo 'Provide a repository name' read -r -p $'Repository name:' repoName done
我们可以这样做:
- 当 repoName 变量未被分配时(
while [ -z "$repoName" ]
)
- 将此信息打印到控制台(
echo '提供一个版本库名称'
)
- 然后读取用户提供的任何输入,并将输入分配给
repoName
变量(read -r -p $'Repository name:' repoName
)
- Author:无常 Anitya
- URL:https://anitya.fun/article/0af3fb0a-f817-4e6b-aeec-89c58b2b0df2
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!