命令行入门:先学会走路,再学会找东西
把终端当成一间有房间、抽屉和门锁的屋子。先走一圈,再写张便条,最后让小工具接力干活。七课,每课一个可以重来的沙盒。

第一次打开终端,最令人不安的也许不是黑底白字,而是它什么都没摆出来。
没有文件图标,也没有“下一步”。光标一闪一闪,像在等你知道该去哪。
不妨把它想成一间关了灯的屋子。文件还在,房间也还在,只是这次要用文字问路。先问“我在哪”,再问“这里有什么”。不需要先背一本命令大全,四个词就够走第一圈。
第 1 课:先问自己在哪
pwd 问位置,ls 看周围,cd 走进另一间屋子,cat 把文件读出来。
你站在“文档”门外时,ls 会告诉你有这间屋子;走进去以后再 ls,看到的才是里面的简历和笔记。命令没变,脚下的位置变了。
走多了,就会想抄近路。cd .. 回上一级,cd 什么都不跟是回家,cd - 是回刚才待过的地方。
路径也有两种说法。“从这里进笔记”是相对路径,比如 笔记;“从根目录沿着这条路走”是绝对路径,比如 /home/kai/文档/笔记。前一种要看你站在哪,后一种以 / 开头,起点固定。
~ 是家目录的缩写。所以 ~/文档/笔记 相当于“先从我家出发”,并不是说家就是整台电脑的根目录。沙盒里家在 /home/kai。你自己的电脑可能是 /Users/名字 或 Git Bash 里的 /c/Users/名字,以 pwd 的输出为准。
如果现在站在笔记里,要读桌面的待办,必须先走回去吗?
第 2 课:给自己留一张便条
屋子认熟了,接下来摆点自己的东西。
mkdir 项目 腾出一间新房间;进去后,echo "第一行" > 说明.md 就能写下一张便条。echo 原本只是把文字说出来,> 把这句话接到文件里。
这里有两个长得很像的箭头:> 换一张纸,>> 接着往下写。 文件已经有内容时,一个箭头会覆盖,两个箭头会追加。
刚才 cp 留下原件,复制了一份;mv 则给副本换了名字。若目标是一个已有目录,mv 做的就是搬家。目标如果是已有文件,cp 和 mv 都可能覆盖它,出手前先看看目标是什么。
文件名里有空格怎么办?用一对英文引号把它抱成一个整体:
cp "会议 记录.txt" "会议 记录.bak"
这是一份来源、一份副本,不是四个文件名。中文弯引号在文章里很好看,在真实 shell 里却不能代替这对直引号。
第 3 课:让 ls 把话说全
文件一多,只看名字就不够了。ls 有两个常用的小开关:-l 让它多说些细节,-a 让它把点开头的隐藏名称也列出来。两个一起用,就是 ls -la。
隐藏文件并没有隐身术。它们只是平时不出现在名单上;知道名字,仍然可以照常访问,前提是你有权限。
日志很长时,cat 像把整卷纸一口气摊开。只想看开头,换成 head -n 3 文件;只关心最后发生了什么,用 tail -n 2 文件。wc -l 文件 则帮你数换行。
这份日志有四十行,所以 head 给你第 1–3 行,tail 给第 39–40 行。读一头一尾,往往已经能决定接下来该找什么。wc -l 严格数换行符。本文的练习文件每行都以换行结尾;如果最后一段没有结尾换行,人眼数的行数可能多一。
真实终端还可以用 less 文件 慢慢翻,按 q 退出。工具没装齐也没关系,先把这几种读法用顺手。
第 4 课:找的是文件,还是一句话?
“那份番茄菜谱放哪了?”和“哪些笔记提过番茄?”听起来相近,却是两件事。
find 找名字:find . -name "*.md" 从脚下开始,找名称符合这个模式的条目。星号表示这一段可以是别的字符。
grep 找内容:grep 番茄 菜谱/番茄蛋.md 把文件里匹配的行挑出来。想知道在第几行,加 -n。
注意 "*.md" 外面的引号:这是让 shell 先别拆它,把整张搜索条件交给 find。终端背后负责解释命令的程序,就叫 shell;有些符号先由它处理,再交给工具。
tree 可以把房间画成一张地图,但不是每台电脑都预装。没有它,仍然可以用 ls 和 find 找路。
grep 没说话,是不是坏了?
也许只是没找到。真实 grep 找到匹配时通常返回 0,没匹配返回 1,出错返回 2;在 shell 中可以紧接着用 echo $? 看上条命令的退出码。
真实 grep 默认支持正则表达式,想按字面找 a.b 这样的文字,可以用 grep -F。沙盒只实现字面检索,暂不支持完整正则与 $?。
第 5 课:门锁是九个字符
还记得 ls -l 最前面那串字母吗?先看一眼:
-rw-r-----
最前面的 - 说“这是普通文件”。后面九位分成三串钥匙:rw-、r--、---,分别给所有者、所属组、其他用户。在沙盒里,你正好是所有文件的主人。
r 能读,w 能写,x 能执行。数字写法只是把钥匙压缩一下:读记 4,写记 2,执行记 1,加起来就是一组权限。于是 6 是读写,7 是三把都有。
给日记设 600,就是所有者读写,其余两组没有权限。只想给所有者加一把执行钥匙,写 chmod u+x 工具.sh,不用重新配整串。
看到 Permission denied,先别把所有门都拆了。问问是哪个文件、谁的权限、要做什么;很多时候只需要补一把钥匙,不是 chmod 777。
文件的门锁,与房间的门锁
目录的 r 是列出名字,x 是经过或搜索这个目录,w 与里面条目的增删有关。因此文件只读,不等于不能被删除;删除主要看父目录权限,还可能受其他机制限制。
chmod u+x 明确只改所有者;省略 u 的 +x 不等于只给自己,还受 umask 影响。600 也不是加密,管理员仍可能访问。脚本运行失败除了权限,还可能是解释器等问题。沙盒只演示基本权限,不执行真实脚本。
第 6 课:让小工具接力干活
现在你有三封来信,想知道多少行提到了会议。
可以逐封打开,边读边数。也可以把任务交给三个小工具:cat 把信读出来,grep 留下含“会议”的行,wc 数一数。
它们中间用一根竖线连接,叫管道:左边交出来的文字,直接送到右边手里。
cat 来信/一.txt 来信/二.txt 来信/三.txt | grep "会议" | wc -l
结果是 2,表示匹配行数,不是信件数:同一封信可能有多行提到会议。想知道这两行究竟是什么,把最后的 | wc -l 暂时拿掉就行。管道不必一次写完;先让第一段说对,再接下一段。
这样,三个符号也能各归各位了:> 把输出留下,| 把输出传下去,&& 则说“前一步成功,才做后一步”。比如目录建好了再进去,mkdir 新目录 && cd 新目录。
它们不是同一种连接。管道里流动的是文本,&& 看的是命令有没有成功。grep 没找到会议时,就不会让 && 右边的“找到了”继续说出来。
第 7 课:收拾房间,先别急着扔
最后一间屋子有点乱:旧备份夹在新笔记里,临时目录还没清,一份表格放错了地方。
这时最有用的不是更厉害的删除命令,而是一点顺序感:先看全貌,再读候选文件,确认不要了,最后才删。
为什么要把“读”和“删”分两次敲?因为 cat 文件 && rm 文件 只会等 cat 读完,不会等你读完。电脑眼里的“成功”,和人的“确认过了”,不是一回事。
整理完再 ls 或 tree 一次。重要笔记还在,表格回了自己的房间,剩下的每样东西都能解释。这样的一次清理,才算完成。
一张可以回来查的表
| 想做什么 | 从这里开始 |
|---|---|
| 问位置、看周围 | pwd、ls |
| 走进去、退一级、回家 | cd 目录、cd ..、cd |
| 读整份、读头、读尾 | cat、head、tail |
| 建目录、复制、搬家 | mkdir、cp、mv |
| 按名字找、按内容找 | find、grep |
| 给所有者加执行权限 | chmod u+x 文件 |
| 不知道一个选项是什么意思 | man 命令 或工具自己的帮助 |
接下来,给自己布置一张小书桌
在真实电脑上找一个新的空目录,写三行笔记,复制一份,只改副本。然后用 grep 找到其中一句,再接上 wc 数一数。
没有任务条也没关系。忘了可以回来查;命令没输出时,就用 pwd、ls、cat 看看它刚才做了什么。终端的安静,很多时候只是“事情办完了”,不需要每次都吓一跳。
沙盒不是完整 Bash:没有真实用户、后台进程或完整符号链接,也不能运行任意脚本。想系统继续学,可以读 The Linux Command Line;要查语法与工具细节,有 Bash 手册 和 Coreutils 手册。macOS 的部分工具选项以本机手册为准。
接下来,也可以去给这些文件拍几张 Git 快照。屋子还是那间屋子,这次开始给它留一点历史。