大家好,欢迎来到IT知识分享网。
前言
在我大学七年内,传统的计算机科学课程会学习操作系统、形式语言、组成原理和机器学习等各种高大上课程,但几乎没有针对工具(例如 Git、VIM、Shell 之类)来做专门的讲解,这导致很多人毕业甚至工作了多年都闹不清楚这些常见工具该怎么用,不过也能理解,毕竟每个人都是从萌新阶段过来的嘛。本系列文章面向新手,希望可以给新手讲清楚 Shell 和它的初中高级用法。
Part 1:Shell 是什么
咱们都知道,图形化界面无孔不入,电脑、手机、汽车、ATM 等等全都用图形化界面,用手指点点鼠标和键盘就能操作这些设备,对于非计算机行业的人来说,使用图形化界面足够发挥设备的 90% 功能了。但是对计算机领域内的人,图形化界面能发挥的作用还是比较有限,毕竟我们不能点一个不存在的按钮吧,那为了充分发挥计算机提供的功能,我们需要使用文本界面:Shell。
举个例子,我用鼠标双击打开一个 myfile.txt 文件,和我在终端里输入一行命令:
nano myfile.txt
如果在 Windows 下,输入终端的命令可能是:
notepad myfile.txt
无论是你操作鼠标打开文件,还是在终端中输入命令,达成的结果都是一样的。
所以我们可以简单的理解为,Shell 是一个解释用户输入的命令(就像我们操作鼠标键盘一样)并将命令传递给操作系统执行的程序。常见的 Shell 包括 bash、zsh(用于Linux) 和 PowerShell(用于Windows) 等。通过 Shell,我们可以直接控制计算机执行各种任务,如文件管理、系统配置和软件安装等。
刚刚提到了终端,这又是什么?
我们可以通过比喻来形象表示这俩货的关系:
终端是一个窗口,你可以在里面输入命令来告诉计算机做事。它就像一个聊天框,你输入文字,计算机会按照你的指令做出相应的动作。
Shell 是在终端中运行的程序,用于执行你输入的命令。你输入的命令会被 Shell 解释,然后 Shell 会指示计算机执行这些命令。可以把它理解成是一个帮助你和计算机交流的工具。大多数操作系统的 Shell 并不是与底层内核的直接接口,实际上,Shell 只是一种特殊的应用程序,它们使用内核 API 的方式与其他应用程序使用内核 API 的方式完全相同。
常见的终端(聊天框)大概有 Terminal(Mac 内置的)、iTerm2(也是 Mac 上常用的)、GNOME Terminal(一些 Linux 发行版默认的终端)、Konsole(KDE 的默认终端)、Command Prompt(cmd,Windows 上内置)、PowerShell(Windows 内置)、Windows Terminal(Windows 上的新终端,还挺好用)。
常见的 Shell 有 bash(事实上的 Linux 标准,几乎全部 Linux 发行版都内置)、zsh(macOS 的默认 Shell)、cmd.exe(Windows上)、WSL(可以利用它在 Windows 上运行 Linux 的 Shell)。
简单总结
终端是一个窗口,你可以在里面输入命令;Shell 是在终端里运行的程序,它解释并执行你输入的命令。
Part 2:使用 Shell
以下内容以 Debian 12 为例,我建议读者搞一个虚拟机来学 Shell 比较好,一方面干我们这行的离不开 Linux 发行版,另一方面无论是 cmd.exe 还是 power shell(这两个是 Windows 下的 Shell)都与 Linux 下的 Shell 有语法和命令上的差异。
首先打开终端,你的电脑会显示类似这样的界面:
上面显示了一行信息(要记住,你操作终端就是在聊天框内和计算机沟通,计算机说什么你要看懂才行):
ib@debian:~$
ib:这是当前登录用户的用户名。
@:这是一个分隔符,表示用户名和主机名之间的分隔。
debian:这是主机名(就是你这台电脑的名字)。
::冒号是另一个分隔符,表示主机名和当前工作目录之间的分隔
~:这是当前工作目录的缩写,表示当前用户的主目录(Home 目录),工作目录就是你当前在终端里操作的那个文件夹。就像你用电脑时会打开不同的文件夹来查看和管理文件,在终端里,你通过命令进入和操作这些文件夹,这个文件夹就是你的工作目录。
$:这是提示符的结尾,表示当前是普通用户。如果你是以 root 用户(最高权限)登录,提示符一般是 #。
所以,ib@debian:~$ 表示,当前操作的用户是 ib,这台计算机的名称是 debian,当前工作目录是 ~(即用户 ib 的主目录),提示符 $ 表示这是一个普通用户,而非最高权限的 root 用户。
输入第一个命令
在终端内输入,并按 enter 确认输入:
date
不出意外的话,这个聊天框内的回复如下图:
这个例子中,我们让 Shell 执行了 date 这个程序,执行完毕后,计算机会再次等待我们输入下一条命令,这时就会再次显示:
ib@debian:~$
我们输入的第一条命令很简单,也很傻,但是没关系,我们得理解这里面的原理。
解释
当输入 date 时候,到底发生了什么能让计算机返回给我们年月日时呢?这个看似简单的命令在计算机内部有如下步骤(精简版):
- 在终端中键入 date 并按下回车键,这时终端程序将输入的字符传递给 Shell 程序。
- 由于这个输入包含回车,Shell 程序检测到回车字符,它就知道输入命令结束了。
- Shell 读取并解析输入的命令 date,发现这确实是一个命令,而不是变量或者内置命令(内置命令 built-in commands 是由 Shell 本身直接实现和执行的命令,而不是像 date 那样的外部可执行程序)。
- Shell 查找环境变量 $PATH(后面解释环境变量是什么),查找名为 date 的可执行文件。
- Shell 创建一个新的子进程(fork),用于执行 date 程序,date 程序获取当前的系统日期和时间,把当前的日期和时间输出到标准输出(终端)。
- date 程序执行完毕后,向父进程(Shell)发送一个信号,表示它已经完成执行。
- Shell 接收到子进程终止的信号,恢复控制权,就可以显示新的提示符,等待我们输入下一个命令了。
总结
当我们在终端中输入 date 并按下回车键时,Shell 接收并解析命令,查找并加载 date 程序,然后通过创建子进程来执行该程序,并将结果输出到终端。date 程序执行完毕后,Shell 恢复控制权,等待下一条命令的输入。
Part 3:环境变量
在前面输入 date 并执行的流程时,我们提到了环境变量。接下来我们还要了解一下环境变量。
什么是环境变量
环境变量是一种特殊的变量,用来存储计算机系统和运行在其上的应用程序所需的配置信息。做个比喻,你的计算机就像一个大厨房,而环境变量就像是厨房里的各种工具和配料标签,它们告诉某一个厨师( Shell )哪里可以找到所需的工具和食材,以及如何使用它们。
环境变量的作用
我们继续用厨房来打比方,环境变量的作用如下:
- 告诉系统去哪里找工具:例如 PATH 变量,它告诉系统在哪些橱柜里去找可执行文件(程序),回到刚刚执行 date 程序的例子,环境变量需要告诉 Shell 去哪里找到 date 这个可执行程序。
- 存储重要信息:比如 HOME 环境变量,它能告诉系统你的“家”在哪里(即你的主目录)。
- 配置和控制程序行为:某些环境变量可以调整程序的运行方式,就像调料可以改变菜的味道。例如 LANG 变量,它像是告诉系统你喜欢用哪种调料(语言)。当你在终端中运行一个程序时,系统会根据 LANG 变量的值来决定使用哪种语言环境,LANG 值可以是 en_US.UTF-8(英语),也可以是 fr_FR.UTF-8(法语)。
眼见为实
讲了半天,环境变量到底长啥样?展示一下吧,例如环境变量 PATH,我们在终端输入:
echo $PATH
输出:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PATH 是一个系统环境变量,用于指定操作系统应在何处查找可执行文件(用厨房的例子比喻,可以认为 PATH 变量存储的是厨具清单,厨师能根据这个清单找到微波炉、铲子之类的工具)。当你在命令行中输入一个命令时,Shell 会按照 PATH 环境变量中指定的目录顺序搜索该命令对应的可执行文件。如果找到了,Shell 就会执行它。
当我们在终端输入 date 并按下回车时,Shell 会执行以下步骤:
- 读取 PATH 变量:Shell 会读取当前的 PATH 变量,确定搜索命令的目录列表,上面输入 echo $PATH 得到的输出就是目录列表。
- 按顺序搜索目录:Shell 会依次在这些目录中查找名为 date 的可执行文件。首先搜索 /usr/local/sbin 目录,找不到 date;然后搜索 /usr/local/bin 目录,找不到 date;接着搜索 /usr/sbin 目录,还是找不到 date;最后搜索 /usr/bin 目录,找到 date 文件。
- 执行命令:找到 date 文件后,Shell 会执行这个文件,输出当前日期和时间。
命令、变量和内置命令
前文中有提到,date 程序是命令,实际上在 Shell 中,命令、变量和内置命令是三个不同的的概念。
命令
命令一般指的是外部可执行文件,即独立于 Shell 程序的二进制文件或脚本。这些文件通常位于系统的某个目录中,例如/bin /usr/bin 下等,常见的命令有 date 啊 ls 啊 grep 啊之类的。
更专业的叫法:
- 外部命令:强调它们是独立于 Shell 的可执行文件。
- 可执行程序:因为它们可以直接由操作系统执行。
- 二进制文件或脚本:根据它们的形式(编译的二进制文件或解释的脚本)。
当我们在 Shell 中输入一个命令并按下回车键,Shell 会在系统路径中查找对应的可执行文件并执行它。
内置命令
内置命令是由 Shell 自身直接实现和执行的命令。它们是 Shell 的一部分,不需要外部的可执行文件,例如 cd echo exit pwd 之类的,内置命令无需调用外部程序,直接由 Shell 解释执行,能稍微快点。
变量
这个不用解释了吧,就和代码一样,可以定义存储字符串、数字之类。
怎么shell还有变量呢?
等等,Shell 还有变量?Shell 不是在终端中运行的程序,用于执行我输入的命令吗?它当然是一个终端中运行的程序,但它还是一个类似 Python 的编程环境,我们可以写代码在 Shell 中执行复杂的操作。大家常听说 Shell 脚本,例如我们在 Github 上 Clone 下来的项目,有些就在根目录有一个名叫 Install.sh 的 Shell 脚本,可以用于自动化软件或应用程序的安装过程,这个脚本可以包含从下载文件、设置权限、配置环境变量到执行安装命令的所有步骤。
我们可以类比 Python。Shell 和 Python 都可以解释和执行代码,支持变量、条件语句和循环等编程结构。然而,Shell 更侧重于系统级任务和操作系统交互,而 Python 则是一个功能更为全面的通用编程语言。我们可以更好地利用 Shell 和 Python 来完成不同类型的任务。
Part 4:总结
本文的思维导图:
这个导图是基于本文内容临时画的,属于临时试用版,等写完整个系列我就画一个完整的分享给大家。
这也是本系列的第一篇文章,我尽量多用比喻的形式来讲解,希望大家可以从本文了解了 Shell 是什么,终端和 Shell 之间的关系,以及一些相关概念例如环境变量、内置命令和 Shell 本身作为解释器可以运行 Shell 脚本的能力。我们下期再见!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/84508.html