这是《与 Shell 对话》系列的第一篇。这个系列从零开始搭建终端的使用能力——不讲抽象理论,只讲你手边就能敲出来的东西。第一篇的目标很简单:理解终端是什么、知道自己在哪、能独立操作文件。 不需要背,只需要跟着敲一遍,让手指先记住。
《与 Shell 对话》系列一共七篇:终端是你的新桌面 → 看与找 → 流水线与重定向 → 面向系统的操作 → 让你的 Shell 认识你 → 从命令到脚本 → 遇到问题怎么办
| 关键词 | 一句话说明 |
|---|---|
| 终端(Terminal) | 一个接收文字指令、交给计算机执行、再显示结果的窗口——没有图标,只有文字 |
| Shell | 终端背后负责解释你输入的文字的程序。你的 Mac 默认是 zsh(Z Shell) |
| 提示符(Prompt) | 终端告诉你"可以输入了"的符号,通常是 ~ % 或 $ |
| 命令结构 | 所有命令的共同公式:命令 [选项] [参数] |
| 当前工作目录 | Shell 永远站在某个文件夹里。所有命令默认作用于这个文件夹 |
| 绝对路径 vs 相对路径 | 从根(/)开始的完整地址 = 绝对路径;从当前位置出发的便捷写法 = 相对路径 |
| 通配符(Wildcard) | * 匹配任意字符,? 匹配单个字符——批量操作的快捷键 |
| Tab 补全 | 按 Tab 自动补全命令或路径——你会用到最多的一个按键 |
| man 手册 | 每个命令的使用说明书,man 命令名 即可查看 |
| 标准输出 / 错误输出 | 命令的结果走 stdout,出错信息走 stderr——两条不同的通道,默认都显示在屏幕上 |
你打开访达(Finder),看到一个文件夹,双击进去,看到文件——这是图形界面做的事。你在终端里输入 ls,看到文件列表,输入 cd 文件夹名 走进去——这是终端做的事。它们说的是同一种语言,只是用户界面不同。 访达把操作画成图标和窗口,终端把操作写成文字和回车。
不是终端比图形界面「高级」——是在某些场景下,文字比图标更精确、更快、更可重复。当你需要一次重命名 200 个文件时,一个命令 0.3 秒搞定,而图形界面你要点 200 次右键。
打开「终端.app」(在「启动台 → 其他」里,或者按 Command + 空格 搜索「终端」Terminal),你会看到类似这样的东西:
Last login: Wed Jun 3 10:00:00 on ttys000
aodesai@MacBook-Pro ~ %
拆开来,每一部分代表什么:
| 元素 | 例子 | 含义 |
|---|---|---|
| 用户名 | aodesai | 当前登录的账户——就是你自己 |
| 主机名 | MacBook-Pro | 这台电脑的名字 |
~ | 波浪号 | 你的用户文件夹(/Users/aodesai/)的缩写——任何地方看到 ~,就是在说这里 |
% | 提示符结尾 | Shell 说「我准备好了,你输入吧」 |
| 闪烁光标 | ▊ | 你输入的文字会出现在这里 |
~这个符号是你在终端里最常看到的。它不是装饰——在任何路径中都可以用它。~/Desktop就是「我的桌面」,~/Downloads就是「我的下载」。记住这个符号,后面每时每刻都会用到。
终端里所有的命令都长一个样。记住了这个公式,你就能看懂任何命令的基本结构:
命令 [选项] [参数]
| 位置 | 是什么 | 例子 |
|---|---|---|
| 命令 | 你要做什么——唯一必须有的部分 | ls(列出文件) |
| 选项 | 调整命令的细节行为——以 - 开头 | -l(详细格式)、-a(显示隐藏) |
| 参数 | 命令作用的对象——哪个文件、哪个目录 | ~/Desktop(列出桌面的内容) |
组合起来:
ls -la ~/Desktop
└┴┘ └─┴─┘ └───┴─────┘
命令 选项 参数(目标)
不需要记住所有选项。 你只需要知道:- 加字母就是选项。用的时候查 man 命令名,或者先只用 -l 和 -a 两个选项,它们覆盖 80% 的场景。
选项可以合并简写:-l -a 可以写成 -la,效果完全相同。
想不起选项时怎么办——man 命令。 在任何时候,输入 man 命令名 可以查看该命令的完整使用说明书:
man ls # 查看 ls 的手册
man cp # 查看 cp 的手册
手册用 less 分页器显示(后面会细讲)。现在你只需要知道:空格翻页,q 退出。 试试在终端里输入 man ls,按空格翻几页,然后按 q 退出。
一个重要的心理模型:你输入的每一个命令,本质上都是在执行一个程序。
ls是一个叫ls的程序,cp是一个叫cp的程序。~里的/bin/ls就是这个程序在硬盘上的位置。Shell 找到它、运行它、把结果打印在屏幕上。所有命令都是程序——包括pwd、cd、echo。区别在于有些是内置在 Shell 体内的(cd),有些是独立的可执行文件(ls)。
clear——清屏。屏幕太乱时输入,终端内容全部清空,只留顶部一个干净的提示符。不会删除任何东西,只是把显示滚回顶部。
exit 或 Ctrl + D——退出终端。关闭当前 Shell 会话。在有些场景下(比如你 SSH 连接了远程服务器),exit 会断开连接。
Ctrl + C——终止当前运行的命令。按错了命令、命令卡住了、不想等了——按 Ctrl + C 停止它。
# 你打错了或者不想等了
ping google.com
^C ← 按 Ctrl + C,立刻停止
这三个操作——清屏、退出、中断——是你的安全网。无论终端变成什么状态,
Ctrl + C总能让你回到干净的提示符。
这个问题是终端使用者的起点。图形界面里你永远看得出来自己在哪个文件夹——标题栏有名字。终端里你不会自动知道,所以需要两个命令来确认。
pwdpwd
/Users/aodesai
pwd = Print Working Directory(打印工作目录)。它回答一个简单的问题:我现在站在哪个文件夹里?
输出是一个从 / 开始的完整路径。这是你的 Mac 的文件系统中最顶层的目录,叫「根目录(root directory)」。从根开始,一层层用 / 分隔到你现在的位置。
| 路径 | 什么意思 |
|---|---|
/ | 根目录——整个文件系统的起点 |
/Users | 根目录下的 Users 文件夹——存放所有用户账户 |
/Users/aodesai | 你的用户文件夹——你的桌面/下载/文档都在这里面 |
/Users/aodesai/Desktop | 桌面文件夹 |
如果你迷路了,先敲 pwd。它告诉你坐标。
把
/想象成你公寓大楼的大厅。你要去 3 楼的 302 室——这就是/3楼/302。你要去地下车库的 B2 层——/B2。文件系统的/就是大楼的门厅,所有东西都从这里出发。
lsls
Applications Desktop Documents Downloads Library Movies Music Pictures
ls = List。列出当前目录下的所有内容。这是你用最多次的命令,没有之一。
不加任何选项时,它只显示文件名。颜色默认:蓝色是文件夹,黑色是文件(取决于你的终端配色)。
你也可以让 ls 看其他文件夹的内容:
ls ~/Desktop
领域 图片.png 文档.pdf
ls /Applications
App Store.app Calculator.app Calendar.app ...
cdcd Desktop # 进入 Desktop 文件夹
pwd # 确认——现在在 /Users/aodesai/Desktop
/Users/aodesai/Desktop
cd .. # 返回上一级文件夹
pwd
/Users/aodesai
cd = Change Directory。它改变你的当前所在位置。注意:cd 不会显示任何输出。 成功的话什么都不会打印,只是提示符里的 ~ 变成了 ~/Desktop 之类的。这不代表出错了——这是 Unix 的做事方式:不出声就是最好的消息。
| 写法 | 跳到哪里 |
|---|---|
cd 文件夹名 | 进入当前目录下的某个子文件夹 |
cd .. | 返回上一级(父目录) |
cd ~ | 无论在哪,直接回用户文件夹(家目录) |
cd / | 返回根目录 |
cd - | 回到上一个去过的目录(在两个位置之间来回跳时极有用) |
cd ../../ | 一次上两级 |
关于
..:每个文件夹里都有两个隐藏的「指针」——.指向自己,..指向父目录。所以cd ..的意思是「我要去父目录」。ls -la就能看到它们:.和..永远存在,删不掉。
给 cd 或 ls 传一个路径时,有两种写法:
| 路径类型 | 以什么开头 | 例子 | 无论你在哪,结果都一样吗 |
|---|---|---|---|
| 绝对路径 | / | cd /Users/aodesai/Desktop | ✅ 是——从根出发,方向明确 |
| 相对路径 | 字母或 . 或 .. | cd Desktop | ❌ 否——基于当前位置计算 |
绝对路径:从 /(根)开始写完整路线。精确,但啰嗦。
# 无论当前在哪,这个命令都通往同一个地方
ls /Users/aodesai/Desktop/领域/生活/网络操作手册
相对路径:从当前位置出发,只写接下来的方向。方便,但依赖于你在哪。
# 如果你已经站在 ~/Desktop,这个和上面的效果一样
ls 领域/生活/网络操作手册
一个判断路径类型的小技巧:看第一个字符。 如果是
/,是绝对路径。如果是~,也是绝对路径(因为~会被 Shell 展开成全路径)。如果是字母、.或..,是相对路径。
不想输入长路径时:在终端输入 cd (注意 cd 后面有空格)或 ls ,然后把文件夹从访达里直接拖进终端窗口。路径会自动填入,像变魔术一样。
ls 是本篇唯一值得深入展开的命令——因为你会用最多次。学好了它,后面所有命令都在它的延长线上。
默认的 ls 只显示名字。你经常需要知道更多信息:
| 命令 | 看到什么 | 什么时候用 |
|---|---|---|
ls | 文件名(整齐排列) | 日常看一眼 |
ls -l | 详细列表:权限、大小、修改时间 | 想知道谁可以读写、文件多大、什么时候改的 |
ls -a | 包含隐藏文件(以 . 开头的) | 找配置文件或检查目录是否干净 |
ls -la | 上面两个合起来——最常用的组合 | 绝大多数场景的标配 |
ls -lh | 文件大小以人类可读格式显示(K/M/G) | 想看到 KB/MB 而不是字节 |
ls -t | 按修改时间排序(最新的在前) | 想知道最近改了什么 |
ls -S | 按文件大小排序(最大的在前) | 找大文件 |
ls -R | 递归列出所有子文件夹的内容 | 看整个目录树 |
最常用的组合就是 ls -la——记住这一组,就能应付绝大多数需求。
输入 ls -la ~/Desktop 看到的东西可能是这样的:
drwx------@ 5 aodesai staff 160 6 3 10:00 .
drwxr-xr-x+ 44 aodesai staff 1408 6 3 09:55 ..
drwxr-xr-x 3 aodesai staff 96 6 1 14:20 领域
把这串输出从左到右拆开:
| 位置 | 内容 | 含义 |
|---|---|---|
| 第 1 个字符 | d | 文件类型:d = 目录(文件夹),- = 普通文件,l = 符号链接 |
| 第 2–10 个字符 | rwxr-xr-x | 权限:三组(文件所有者 / 所属组 / 其他人)各三个字母(r=读,w=写,x=执行) |
| 数字 | 3 | 硬链接数(文件夹至少是 2——自己和父目录中的条目) |
| 用户名 | aodesai | 文件所有者 |
| 组名 | staff | 文件所属组 |
| 大小 | 96 | 字节数(加 -h 显示为 96B / 4.5K / 2.3M) |
| 日期时间 | 6 1 14:20 | 最后修改时间 |
| 最后 | 领域 | 文件名 |
刚接触时不需要记这么多。 你只需要知道:
d 就是文件夹,- 就是文件——其他猜不猜都行-h 才容易看懂其他的会在后面几篇自然熟悉。
一个终端老手的习惯:
ls -la是一种肌肉记忆。进入一个新目录,下意识敲ls -la——看一眼就大致知道这是一个什么目录。你会慢慢培养出同样的本能。
ls -la ~/Desktop # 看桌面
ls -la /Applications # 看应用程序文件夹
ls -la .. # 看当前目录的上一级
ls -la ~/Desktop/领域 # 看桌面下的某个子文件夹
所有目录命令都遵循同一个模式:不给参数时作用于当前目录,给参数时作用于你指定的目录。
这些命令对应着访达里的右键菜单——拖拽、复制、重命名、移到废纸篓。在终端里,它们用文字完成同样的动作。
mkdirmkdir 学习笔记 # 在当前目录下新建一个文件夹
mkdir -p 学习笔记/终端/第一篇 # -p 自动创建中间缺失的目录层级
mkdir = Make Directory。不指定路径时就在当前目录下创建。指定路径时可以创建到别处:
mkdir ~/Desktop/测试文件夹 # 在桌面上新建一个文件夹
touchtouch 笔记.txt # 创建一个空文件
touch 笔记.txt 草稿.txt 清单.txt # 一次创建多个
touch 字面意思是「摸一下」。如果文件存在,只更新它的修改时间。如果文件不存在,则新建一个空文件。这是创建空文件最快捷的方式。
cpcp 笔记.txt 笔记备份.txt # 复制单个文件
cp -r 文件夹A 文件夹B # -r 递归复制整个文件夹及其所有内容
cp = Copy。格式是:cp 来源 目标。复制文件夹时必须加 -r(recursive,递归),否则 cp 会拒绝操作,报错 omitting directory。
# 复制到其他目录
cp 笔记.txt ~/Desktop/ # 把笔记.txt 复制到桌面
cp 笔记.txt ~/Desktop/备份.txt # 复制过去并改名
mvmv 笔记.txt ~/Desktop/ # 把文件移到桌面
mv 旧名字.txt 新名字.txt # 重命名——没错,移动和重命名是同一个命令
mv = Move。在 Unix 里,移动和重命名是同一个操作——都是把文件从一个位置挪到另一个位置。如果在同一目录下改名,就是重命名。如果挪到不同目录,就是移动。
一个常见的误区:重命名不需要专门的命令。
mv 旧名 新名就够了。不需要找什么 rename 按钮——在终端里,重命名就是移动。
rm——唯一需要小心的命令rm 笔记.txt # 删除文件
rm -r 文件夹 # 删除文件夹及其所有内容(-r 递归)
rm -rf 文件夹 # 强制删除(-f force),谨慎使用
rm = Remove。终端里删除文件不会进废纸篓。 没有二次确认对话框。按了回车就没了——至少从普通用户的角度来说,很难恢复。
安全小贴士(记住这三个):
rm 时,先用 ls 确认你要删的是什么——你打算删的和你看到的是一回事-r——不加的话 rm 不删文件夹,这其实是保护机制-rf 组合是双刃剑——rm -rf / 会试图删除整个硬盘(现代 macOS 有保护机制阻止这件事,但不要故意试)# 安全做法演示
ls # 先看看当前目录有什么
rm 笔记.txt # 确认无误再删
一个实用建议:给你的
rm加上一个别名alias rm="rm -i"(-i让每次删除前都问你确认)。怎么做?这是我们系列第五篇会详细讲——但你可以先试试在终端里输入这行命令,效果立竿见影。
openopen 笔记.txt # 用默认程序打开(TextEdit)
open ~/Desktop # 在访达中打开桌面文件夹
open . # 在访达中打开当前目录
open -a "Visual Studio Code" 笔记.txt # 指定用 VS Code 打开
open 是 macOS 特有的命令——它把文件交给系统默认的应用来打开。这是终端通向图形界面的一扇门。
在真正上手前,用下面的步骤做一次安全的试操作——所有动作都在一个新创建的临时文件夹里:
# 第一步:在桌面上建一个用来练习的文件夹
mkdir ~/Desktop/终端练习
# 第二步:走进去
cd ~/Desktop/终端练习
# 第三步:确认自己进去了
pwd
/Users/aodesai/Desktop/终端练习
# 第四步:创建几个空文件
touch 日记.md 清单.txt 想法.md
# 第五步:看看它们
ls -la
# 第六步:复制一个
cp 日记.md 日记备份.md
# 第七步:重命名一个
mv 清单.txt 购物清单.txt
# 第八步:新建一个子文件夹
mkdir 存档
# 第九步:把文件移进去
mv 日记备份.md 存档/
# 第十步:看看最终的样子
ls -laR # -R 递归显示子文件夹内容
# 最后:清理练习文件夹
cd ~/Desktop
rm -rf 终端练习 # 全部清除
# 注意:这里用 rm -rf 是安全的——这个文件夹是
# 你刚创建的,里面只有你自己放的练习文件。
# 你清楚自己在删什么,这和无差别地删一个
# 陌生目录完全不同。
把这个练习完整做过一遍,文件操作的几个命令就不会再陌生了。它们和鼠标右键菜单是一回事,你用文字在指挥。
通配符(Wildcard)是终端里一个极小的概念,但它的效果特别大。它让你一条命令操作一群文件。
*——匹配任意数量的任意字符# 假设当前目录下有这些文件:
# 日记1.md 日记2.md 日记3.md 笔记.txt 照片.jpg
ls *.md
日记1.md 日记2.md 日记3.md
rm 日记*
# 删掉了所有以「日记」开头的文件(谨慎!)
cp *.jpg ~/Desktop/
# 把所有 jpg 图片复制到桌面
* 的意思是「什么都行,有或没有都行」。日记* 匹配所有以「日记」开头的文件。*.md 匹配所有 Markdown 文件。
?——匹配恰好一个字符# 文件:日记1.md 日记2.md 日记10.md 日记A.md
ls 日记?.md
日记1.md 日记2.md 日记A.md
# 日记10.md 没出来——因为 ? 只匹配一个字符
? 精确匹配一个字符的位置。日记?.md 配「日记1.md」但不配「日记10.md」。
[abc]——匹配指定范围的单个字符# 文件:cat.md bat.md hat.md fat.md
ls [cb]at.md
cat.md bat.md
# hat 不匹配,因为 h 不在 [cb] 里
ls [a-c]at.md
bat.md cat.md
# 也支持范围:[a-c] = a 或 b 或 c
[abc] 匹配括号内指定的任意一个字符。[a-z] 匹配任意小写字母。[0-9] 匹配任意数字。
通配符不是由命令处理的——是由 Shell 在把命令交给程序之前就展开了。所以 rm *.md 实际上是:Shell 先找到所有以 .md 结尾的文件,把它们列出来,然后交给 rm。程序收到的是展开后的文件名列表,而不是通配符。
# 验证通配符展开——用 echo 看看 Shell 实际上送了些什么
echo *.md
日记1.md 日记2.md 日记3.md 笔记.md
通配符展开是在命令执行之前发生的。这意味着如果你有很大的文件数量(成千上万个匹配项),Shell 会列出一个很长的参数列表传给命令。绝大多数情况下没问题,但这解释了为什么
rm *有时可能遇到「参数列表过长」的错误。这个知识点你现在不需要记——用到时会自然遇到。
终端里鼠标几乎没用。效率来自键盘。下面的快捷键是每天会用到几百次的,现在就开始练肌肉记忆:
| 快捷键 | 效果 | 使用频率 |
|---|---|---|
| Tab | 自动补全命令或路径 | ⭐ 最高频——每输一个命令几乎都会用 |
| ↑ ↓ | 浏览命令历史(上一条/下一条) | ⭐ 最高频——再次执行或微调上一条命令 |
| Ctrl + C | 终止当前正在运行的命令 | ⭐⭐ 高频——卡住/按错时救急 |
| Ctrl + D | 退出当前 Shell,或结束输入 | ⭐⭐ 高频——比打 exit 快 |
| Ctrl + A | 光标跳到行首 | ⭐⭐ 高频——修改命令开头时 |
| Ctrl + E | 光标跳到行尾 | ⭐⭐ 高频——从行首跳回来后 |
| Ctrl + U | 删除光标前的全部内容 | ⭐⭐ 高频——整行命令打错了,重来 |
| Ctrl + W | 删除光标前的一个词 | ⭐⭐ 高频——只删一个词而不是整行 |
| Ctrl + L | 清屏(效果同 clear) | ⭐⭐ 高频——手不离主键盘区 |
| Ctrl + R | 搜索命令历史 | ⭐⭐ 高频——打出几个字符就能找回曾用过的命令 |
| Ctrl + Z | 暂停当前命令(放到后台) | ⭐ 中频——后面第四篇会细讲 |
现在最值得先练的三个:
cd Des 然后按 Tab → 自动补全为 cd Desktop/。如果按了一次没反应(说明有多个匹配),按两次 Tab 会列出所有可能的选项一个会让你舒适很多的小习惯:养成遇到不确定就按 Tab 的习惯。 输入
cd ~/De按 Tab → 变成cd ~/Desktop/。如果路径不存在或拼写有错,按 Tab 不会补全,这就是一个即时反馈——Shell 告诉你「这个路径不对」。把 Tab 当作你的第一救助按钮。
| 命令 | 含义 | 常用变体 |
|---|---|---|
pwd | 我在哪 | 不加参数,没有变体 |
ls | 这里有什么 | -la(详细+隐藏) -lh(可读大小) -t(按时间) |
cd | 去那里 | cd ..(返回上级) cd ~(回家) cd -(回上一个位置) |
mkdir | 新建文件夹 | -p(创建中间层级) |
touch | 创建空文件 | 可一次创建多个 |
cp | 复制 | -r(复制文件夹必须加) |
mv | 移动 / 重命名 | 同一目录内 = 重命名,跨目录 = 移动 |
rm | 删除(不进废纸篓) | -r(删文件夹) -f(强制,谨慎) |
open | 用默认程序打开 | open .(在访达打开当前目录) open -a 程序名 文件 |
clear | 清屏 | 或 Ctrl + L |
本篇提到了但未深入展开的方向,后续篇章会覆盖:
ln 命令,一个文件可以有多个名字. 开头的文件自动隐藏,以及 macOS 特有的 .DS_Store/System、/Library、/Volumes、/tmp 各是什么rm -i 别名保护——给 rm 加确认提示的方法,见第五篇-l(短选项)vs --all(长选项)的由来[!abc]——ls [!a]* 不匹配以 a 开头的文件,只匹配其他rwx 的三个分组与 chmod 的数值模式