Skip to content

第 6 章 终端与 Shell 入门 ​

Part 2 · 命令行生存


引子 ​

黑底白字,一个光标在闪烁。没有图标,没有菜单,没有鼠标右键。

这就是终端。每一个 Linux 老手每天打交道最多的东西,也是每一个新手最害怕的东西。

恐惧来自未知。光标在闪,但你不认识它背后的那套语言——你不知道该敲什么,不知道敲错了会不会爆炸,甚至不知道这个黑框框和那个叫「Shell」的东西到底是什么关系。

这章要做的事情很简单:拆掉这份恐惧。让你认识它,让它听你说话。

Shell 不是黑魔法。它是一种对话——只不过对话的语法比你想象的要严谨那么一点。而那个让你紧张的黑框框,甚至都不是 Shell 本身。


背景与动机 ​

如果你之前用过 Windows,你大概从来没主动打开过命令提示符(cmd)或者 PowerShell。Windows 的哲学是「能点的别敲」,一切都在图形界面里解决。

但 Linux 不一样。准确地说,是嵌入式 Linux 开发不一样。

当你以后用 SSH 连上一块 i.MX 开发板,那块板子很可能连图形界面都没有——你能看到的,就只有一个终端。配交叉编译环境、烧写镜像、查看内核日志、调试驱动……这些事情全部要在命令行里完成。

早点习惯它,后面才不会在每个需要敲命令的环节都卡壳。


概念层 ​

Shell 是什么? ​

你可以把 Shell 理解成一个翻译官——你对着它说人话(命令),它翻译成内核能听懂的指令,转发给内核;内核干完活,把结果丢回来,Shell 再格式化一下,显示在屏幕上给你看。

但「翻译官」这个比喻有一个地方是错的:真正的翻译官只会逐字翻,而 Shell 是有脑子的。它能记住你敲过的命令(历史记录),能猜你想敲什么(Tab 补全),甚至能把一串命令写成「剧本」让它照着演(Shell 脚本)。

这套「你说一句、它做一件」的交互方式,叫做交互式 Shell。后面我们会学到的 Shell 脚本,则是把一整套命令提前写好,Shell 一口气从头执行到尾——相当于给了翻译官一张任务清单,让它自己照单抓药。

Ubuntu 22.04/24.04 的默认 Shell 是 Bash(Bourne Again Shell)。你可以用下面这条命令验证:

bash
# 查看当前使用的 Shell
$ echo $SHELL
# 预期输出
/bin/bash

需要提一句的是:Ubuntu 里 /bin/sh 这个路径指向的不是 Bash,而是 dash(Debian Almquist Shell)。dash 比 Bash 更轻量、启动更快,系统执行脚本时默认用 dash。这个区别在写 Shell 脚本时可能踩坑——如果你的脚本用了 Bash 特有的语法,第一行必须写 #!/bin/bash 而不是 #!/bin/sh。这个问题我们在第 26 章会详细展开。

终端模拟器又是什么? ​

回到那个黑框框。

严格来说,你看到的那个窗口不是 Shell。它叫终端模拟器(Terminal Emulator),是一个把 Shell 包起来的图形窗口。Shell 才是里面干活的那个翻译官,终端模拟器只不过是翻译官面前的那块屏幕加键盘。

这个区分大多数时候不重要——你打开终端,Shell 就在里面等着。但当你遇到「为什么在 Windows Terminal 里能显示颜色,在老式 cmd 里不行」这种问题时,知道「终端」和「Shell」是两层东西,就能帮你找到正确的方向。

Ubuntu 桌面自带的终端模拟器叫 GNOME Terminal。如果你用 WSL2,那你在 Windows 里打开的可能是 Windows Terminal 或系统自带的「Ubuntu」快捷方式——它们本质上都是终端模拟器,连到你 WSL2 里的 Bash。

命令的解剖学 ​

Shell 能听懂的不是自然语言,是一种固定格式的指令。标准结构长这样:

bash
command  [options]  [arguments]

三部分:

  1. command(命令名):动词。「做什么?」——列出文件(ls)、切换目录(cd)、查看手册(man)。
  2. options(选项):副词。「怎么做?」——要看详细信息加 -l,要看隐藏文件加 -a。通常以 - 开头。
  3. arguments(参数):宾语。「对谁做?」——对当前目录,还是对 /usr 目录。

拿 ls 举三个例子,体会一下同一动词的不同用法:

bash
# 光杆司令:只列当前目录的文件名
$ ls
# 预期输出(实际取决于你的目录内容)
Desktop  Documents  Downloads  Music  Pictures  Videos

# 加选项 -l:列出详细信息(权限、大小、时间等)
$ ls -l
# 预期输出
total 24
drwxr-xr-x  2 charlie charlie 4096 Jun 10 10:00 Desktop
drwxr-xr-x  2 charlie charlie 4096 Jun 10 10:00 Documents
drwxr-xr-x  2 charlie charlie 4096 Jun 10 10:00 Downloads

# 加参数 /usr:不看当前目录了,看 /usr
$ ls /usr
# 预期输出
bin  games  include  lib  local  sbin  share  src

Tab 补全:别跟你的键盘过不去 ​

命令成千上万,文件路径更是动辄几十个字符。如果每次都全拼出来,键盘迟早要被敲烂,拼写错误更是家常便饭。

Shell 的设计者早就想到这一点了——Tab 键是你的朋友。

逻辑很简单:你只打前几个字母,然后按一下 Tab。

  • 如果只有一个匹配:Shell 直接帮你把剩下的补全。省时间,还防拼写错误。
  • 如果有多个匹配:Shell 会发出一声提示音。你再按一次 Tab,它把所有可能的候选项列出来供你挑选。

试一下:

bash
# 只输入 if,然后按 Tab 键
$ if
# 如果有多个以 if 开头的命令,再按一次 Tab,Shell 会列出:
if    ifconfig    ifdown    ifquery    ifup

再多输一个字母 c,变成 ifc,再按 Tab——因为只剩 ifconfig 一个匹配,Shell 直接帮你补全。

记住这个习惯:能 Tab 就别手打。 这不是懒,是工程素养。在命令行里,一个字母的错位可能就是「成功执行」和「找不到文件」的区别。

历史记录:你敲过的命令都记着呢 ​

Shell 会把你敲过的每一条命令记下来,存在一个叫 ~/.bash_history 的文件里。

两个最常用的快捷键:

  • ↑ 箭头:往上翻,调出上一条命令。连按可以一直往回翻。
  • Ctrl + R:反向搜索。按下后输入关键词,Shell 会从历史记录里找到最近一条匹配的命令。
bash
# 按 Ctrl+R,然后输入 "apt"
(reverse-i-search)'apt': sudo apt install build-essential

找到了,直接回车执行。不用重新打一遍。

遇事不决问男人:man 和 --help ​

命令太多,参数太杂,谁也记不全。Linux 内置了两套求助机制。

man(manual):

bash
$ man ls

这会打开一份详细的手册页。在里面用上下键滚动,按 q 退出。

--help:

bash
$ ls --help

这会在终端里直接打印一份简要用法说明,不用进入分页模式。大部分命令都支持这个选项。

两个怎么选?想快速看一眼用法,用 --help;想彻底搞懂某个命令的所有行为,用 man。


实践层 ​

4.1 打开终端 ​

在 Ubuntu 桌面上,打开终端有三种方式:

  1. 快捷键:Ctrl + Alt + T——这是最快的。
  2. 应用菜单:搜索「Terminal」或「终端」。
  3. 右键桌面:选择「在终端中打开」。

如果你用的是 WSL2,在 Windows 搜索栏输入「Ubuntu」点击打开即可,或者用更强大的 Windows Terminal(从 Microsoft Store 免费安装)。

打开后,你会看到类似这样的一行:

bash
charlie@ubuntu:~$

这行叫命令提示符。我们来拆解一下:

部分含义
charlie当前用户名
@分隔符
ubuntu主机名(你装系统时起的)
:分隔符
~当前所在目录。~ 是家目录的简写
$权限标识。$ 表示普通用户,# 表示 root

光标在 $ 后面闪烁——系统在等你下命令。

4.2 敲下你的第一条命令 ​

bash
# 显示当前日期和时间
$ date
# 预期输出
Wed Jun 11 14:30:00 UTC 2026

没有爆炸。Shell 听懂了,内核执行了,结果打印出来了。

再来几条,找找感觉:

bash
# 你是谁?
$ whoami
# 预期输出
charlie

# 这台机器的内核版本
$ uname -r
# 预期输出
5.15.0-XX-generic
# 实际输出可能不同,取决于你的系统版本

# 清屏
$ clear

clear 会把屏幕清干净,只留一行光标。快捷键 Ctrl + L 效果相同。

4.3 求助工具实战 ​

当你拿到一个陌生命令,不知道怎么用——别搜百度,直接问系统。

bash
# 用 man 查看 ls 的完整手册
$ man ls
# 在里面用上下键滚动,按 q 退出

# 用 --help 快速查看用法
$ ls --help
# 预期输出(截取)
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

  -a, --all                  do not ignore entries starting with .
  -l                         use a long listing format
  -h, --human-readable       with -l, print sizes in human readable format

养成一个习惯:遇到不会用的命令,先 --help,再 man。 这个习惯会跟你的整个职业生涯。

4.4 命令提示符的秘密 ​

还记得引子里说的那个光标在闪吗?现在你再看那行提示符,它已经不陌生了。

但还有一个细节值得注意——当你在终端里输入 sudo su 切换到 root 用户后,提示符会变:

bash
$ sudo su
[sudo] password for charlie:
# 输入密码时屏幕不会显示任何字符,盲打后回车即可

root@ubuntu:/home/charlie#

注意末尾:从 $ 变成了 #。这是 Shell 在提醒你——你现在手里拿着最高权限,每一个回车都可能造成不可逆的后果。

⚠️ 高危提醒 在 # 提示符下,你拥有对整个系统的绝对控制权。日常操作请务必退回普通用户(输入 exit),只在需要时用 sudo 临时提权。

退出 root:

bash
root@ubuntu:/home/charlie# exit
exit
charlie@ubuntu:~$

回到 $,安全了。


练习题 ​

走到这里,终端应该不再让你紧张了——或者你以为不紧张了。下面几道题试试手,建议自己敲一遍再看提示。

练习 6.1 ⭐(理解)

打开终端,依次执行 echo $SHELL 和 echo $0。两个输出一样吗?为什么?这和「登录 Shell」与「子 Shell」的区别有关。

提示:$SHELL 记录的是你的默认 Shell,$0 记录的是当前正在运行的那个。

练习 6.2 ⭐⭐(应用)

用 man 查看 history 命令的手册。找到 -c 选项是干什么用的,然后思考:在什么场景下你会需要清空命令历史?

练习 6.3 ⭐⭐⭐(思考)

如果一个命令同时支持 -h 和 --help,它们的行为可能不同吗?写一条命令验证你的猜想。想一想,为什么有些命令用 -h 表示「帮助」,有些用 -h 表示「人类可读」(比如 ls -h)——选项命名冲突的问题是怎么产生的?


本章回响 ​

这一章真正在做的事情,不是教你敲了哪几条命令——而是帮你拆开了一个认知上的黑盒:你面对的那个黑框框,其实是两层东西叠在一起的。外面那层叫终端模拟器,负责显示;里面那层叫 Shell,负责翻译你的指令、和内核对话。把它们搞混不会出什么大事,但当显示出了问题、行为不符合预期的时候,知道该去怪哪一层,会让你省掉很多瞎猜的时间。

Shell 这个翻译官比它看起来要能干得多。Tab 补全帮你防错,历史记录帮你偷懒,man 和 --help 帮你自助。这三样东西加在一起,构成了你在命令行世界里独立生存的基础设施——不需要搜索引擎,不需要问别人,系统本身就能回答你的大部分问题。

还记得开头那个光标在闪的画面吗?现在你再看它,它不再是一个你不知道该怎么回应的问号了。你知道它背后站着一个叫 Bash 的翻译官,你知道该怎么跟它说话,你甚至知道说错了可以去查手册。恐惧的消除,不一定需要掌握多少东西,有时候只需要搞清楚「面前这个东西到底是什么」。

下一章,我们要让这个翻译官干点实事——在文件系统的迷宫里认路、导航、找到你想要的文件。届时你会发现,今天学的命令结构(动词 + 副词 + 宾语)会反复出现在每一个新命令里。


← 上一章下一章 →

v1.0.4-37-gc79a127 · c79a127 · 2026-09-29