本章要解决的问题
- 怎样在计算机的目录之间移动?
- 怎样查看已有文件和目录?
- 怎样准确指定某个文件或目录的位置?
学习后,你应能解释文件与目录的联系和区别,把绝对路径与相对路径相互转换,写出指向具体文件或目录的路径,使用选项和参数改变命令行为,并利用 Tab 补全减少输入。
操作系统中管理文件和目录的部分称为文件系统。文件保存信息,目录也称文件夹,可以容纳文件和其他目录。Shell 中有用于创建、检查、重命名和删除文件与目录的常用命令;本章先打开 Shell,练习查看位置和浏览目录。命令示例中的 $ 是提示符,不需要输入;“示例输出”来自课程情境,会因机器与系统而不同。
确认当前工作目录
先运行 pwd,它是 print working directory 的缩写,即打印工作目录。在一次 Shell 会话中,我们总位于某个当前工作目录。许多命令会从这里读取或写入文件,因此执行前知道自己在哪里很重要。
$ pwd
示例输出:
/Users/nelle
这里 /Users/nelle 是课程人物 Nelle 的主目录。
不同系统的主目录
主目录的路径随操作系统变化。Linux 中可能是 /home/nelle;Windows 中可能是 C:\Users\nelle,旧系统也可能使用 C:\Documents and Settings\nelle。本章沿用 macOS 示例;Linux 或 Windows 的实际结果会略有不同。
后面的相对路径练习假设起始位置是主目录。如果 pwd 输出别的位置,先用后文介绍的 cd 回到适当位置,否则示例路径可能不存在。
理解主目录之前,先看看 Nelle 的文件系统结构。你的机器可能组织得相似,但不会完全一样。
文件系统像一棵倒置的树。最上面的根目录包含其他目录,单独用 / 表示。它也是 /Users/nelle 开头的斜杠。根目录下面有 bin、data、Users、tmp 等目录,分别用于存放部分程序、数据、用户个人目录和临时文件等。
/Users/nelle 位于 /Users 中;/Users 又位于根目录 / 中。斜杠有两个作用:位于路径最前面时表示从根目录开始,位于路径内部时分隔各层目录名。
在 /Users 中,Nelle 的同事 imhotep 和 larry 也各有自己的目录,分别为 /Users/imhotep 和 /Users/larry。本章人物 Nelle 的主目录是 /Users/nelle。新打开的终端常从主目录开始,但应以 pwd 的实际输出为准。
查看目录内容
ls 会列出当前目录中的文件和目录名:
$ ls
示例输出:
Applications Documents Library Music Public
Desktop Downloads Movies Pictures
系统和个人配置不同,实际结果也会不同。加上 -F,可以让 ls 用末尾标记区分条目类型:/ 表示目录,@ 表示链接,* 表示可执行文件。某些配置还会用颜色区分类型。
$ ls -F
示例输出:
Applications/ Documents/ Library/ Music/ Public/
Desktop/ Downloads/ Movies/ Pictures/
示例中这些条目都是子目录。没有类型标记的普通条目通常是文件。
清理终端显示
屏幕内容过多时,可以使用 clear -x。此前输入的命令仍可通过上下方向键调用,保留的输出可在终端中滚动查看。部分配置中的 clear 也会清除滚动缓冲区;clear -x 可避免这种行为,Control-L 是另一种清理屏幕的常见方式。选项是否支持仍取决于实际工具实现。
获取命令帮助
ls 还有许多选项。两种常见的帮助入口是 --help 和 man;你的环境可能只提供其中一种。Linux 与 Git Bash 中通常可使用:
$ ls --help
Linux 与 macOS 中通常可查看手册:
$ man ls
Shell 内建命令的帮助
有些命令是 Bash 自身的一部分,而不是文件系统中的独立程序。例如 cd 是内建命令。如果 man cd 显示 No manual entry for cd,可试用 help cd。Bash 的 help 专门用于查询内建命令用法。
--help 选项
许多从 Bash 运行的程序接受 --help,用它显示用法和选项:
$ ls --help
下面保留课程中的英文帮助输出,便于与工具逐字比对:
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if neither -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options, too.
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
-b, --escape print C-style escapes for nongraphic characters
--block-size=SIZE scale sizes by SIZE before printing them; e.g.,
'--block-size=M' prints sizes in units of
1,048,576 bytes; see SIZE format below
-B, --ignore-backups do not list implied entries ending with ~
-c with -lt: sort by, and show, ctime (time of last
modification of file status information);
with -l: show ctime and sort by name;
otherwise: sort by ctime, newest first
-C list entries by columns
--color[=WHEN] colorize the output; WHEN can be 'always' (default
if omitted), 'auto', or 'never'; more info below
-d, --directory list directories themselves, not their contents
-D, --dired generate output designed for Emacs' dired mode
-f do not sort, enable -aU, disable -ls --color
-F, --classify append indicator (one of */=>@|) to entries
... ... ...
短选项与长选项都存在时,交互输入用短选项可减少敲键次数;脚本中的长选项通常更容易阅读,因为脚本往往被读很多次,只输入一次。
不支持的选项
输入程序不支持的选项时,通常会得到类似错误:
$ ls -j
示例错误:
ls: invalid option -- 'j'
Try 'ls --help' for more information.
man 手册
另一种方式是:
$ man ls
终端会显示 ls 的说明与选项。在常见的 less 分页器中,上下方向键逐行移动,b 与空格键翻页;输入 / 后跟搜索词可查找。用 n 查找下一个匹配,用 N 查找前一个匹配。按 q 退出。分页器配置不同,键位可能不同。
也可以在浏览器中查找在线手册,搜索时加上 unix man page 有助于找到相关结果。GNU 提供手册索引及核心工具手册,其中覆盖本课程的许多命令。
练习:更多 ls 选项
ls -l 会怎样?同时使用 -l、-h 呢?长列表会显示一些本章尚未讲解的属性,如权限与所有者,但仍能帮助理解文件。
答案:-l 使用长列表格式,除了名称,还显示文件大小、最近修改时间等信息。-lh 把大小改为更容易阅读的形式,例如用 5.3K 代替 5369。
练习:把最近修改的文件排在最后
默认情况下,ls 通常按名称排序。-t 按修改时间排序,-r 反转顺序。两者合用时,哪一个文件最后显示?可配合 -l 查看修改日期。
答案:ls -rt 会把最近修改的文件排在最后。它适合寻找最近编辑的内容或检查是否生成了新输出。
浏览其他目录
ls 不仅能列出当前目录,也能接受另一个目录路径。例如:
$ ls -F Desktop
示例输出:
shell-lesson-data/
这里命令是 ls,选项是 -F,参数是 Desktop。参数告诉程序要查看哪个目录。如果当前目录下不存在 Desktop,命令会报错。课程假定当前目录是主目录,并已按课程准备说明下载、解压 shell-lesson-data。列表也可能包含桌面上的其他文件与子目录。在多数系统中,Desktop 里的条目会同时显示为图形桌面上的图标;可以对照屏幕上的桌面与 Shell 列表,看看是否如此。
有层次的目录便于管理工作。把几百个文件堆在主目录,像把几百页材料堆在桌上;按用途命名子目录更容易查找。
知道课程数据位于 Desktop 之后,可以继续查看:
$ ls -F Desktop/shell-lesson-data
示例输出:
exercise-data/ north-pacific-gyre/
也可以改变当前工作目录。cd 是 change directory 的缩写;它不修改目录内容,而是改变当前 Shell 所处的位置,类似在图形界面中双击进入文件夹。
逐层进入 exercise-data:
$ cd Desktop
$ cd shell-lesson-data
$ cd exercise-data
成功时 cd 常不输出任何内容。执行 pwd 可确认已进入 /Users/nelle/Desktop/shell-lesson-data/exercise-data。这时不加目录参数的 ls -F 会列出该目录。
$ pwd
示例输出:
/Users/nelle/Desktop/shell-lesson-data/exercise-data
$ ls -F
示例输出:
alkanes/ animal-counts/ creatures/ numbers.txt writing/
回到父目录
进入子目录后,怎样向上返回?下面的尝试会失败:
$ cd shell-lesson-data
示例错误:
-bash: cd: shell-lesson-data: No such file or directory
因为相对路径 shell-lesson-data 会从当前目录查找同名子目录,而不是自动寻找上层。向上移动一级可用:
$ cd ..
.. 表示当前目录的父目录。确认位置:
$ pwd
示例输出:
/Users/nelle/Desktop/shell-lesson-data
.. 通常不会出现在普通 ls 输出里。加上 -a 可显示名称以点开头的条目,包括 . 和 ..:
$ ls -F -a
示例输出:
./ ../ exercise-data/ north-pacific-gyre/
. 表示当前目录,.. 表示父目录。多个短选项通常可合并,例如 ls -F -a 与 ls -Fa 等效。
其他隐藏文件
可能还会看到 .bash_profile 等名称以点开头的文件或目录。它们常保存 Shell 或其他程序的配置。普通 ls 默认省略这些名称,以减少列表中的配置条目。
回到主目录
pwd、ls、cd 是浏览文件系统的三个基本命令。不带参数的 cd 会怎样?
$ cd
用 pwd 检查:
$ pwd
示例输出:
/Users/nelle
不带参数的 cd 回到主目录。迷失在目录层次中时,它很实用。
相对路径与绝对路径
此前用了三个 cd,也可以一次写完各层目录:
$ cd Desktop/shell-lesson-data/exercise-data
用 pwd 和 ls -F 检查是否抵达预期位置。
目前使用的都是相对路径:ls 或 cd 从当前工作目录开始解析路径。绝对路径则从根目录开始,以 / 开头,描述完整位置,不依赖当前目录。
这让我们可以从任何位置回到 shell-lesson-data。先确认完整路径:
$ pwd
示例输出:
/Users/nelle/Desktop/shell-lesson-data/exercise-data
然后进入绝对路径:
$ cd /Users/nelle/Desktop/shell-lesson-data
再次用 pwd 和 ls -F 确认位置。
两个快捷写法
路径开头的 ~ 由 Shell 解释为当前用户的主目录。因此,当主目录为 /Users/nelle 时,~/data 相当于 /Users/nelle/data。这里强调它在路径开头的用法;here/there/~/elsewhere 不会自动展开为 here/there/Users/nelle/elsewhere。
cd - 回到上一次工作目录。连续执行两次,会返回最初位置。cd .. 是向上一层,cd - 是回到上一处;两者不是同一操作。
试着先进入课程目录:
$ cd ~/Desktop/shell-lesson-data
再进入 creatures:
$ cd exercise-data/creatures
然后返回:
$ cd -
你会回到 ~/Desktop/shell-lesson-data。再次执行 cd -,则回到 ~/Desktop/shell-lesson-data/exercise-data/creatures。
练习:绝对路径与相对路径
从 /Users/nelle/data 开始,下列哪些命令能回到主目录 /Users/nelle?
| 命令 | 答案与原因 |
|---|---|
cd . |
不能;. 是当前目录。 |
cd / |
不能;/ 是根目录。 |
cd /home/nelle |
不能;本例主目录是 /Users/nelle。 |
cd ../.. |
不能;上移两层到 /Users。 |
cd ~ |
可以;~ 表示本例的主目录。 |
cd home |
不能;它指向当前目录下的 home 子目录,若存在才会进入。 |
cd ~/data/.. |
可以;写法较复杂,但会回到主目录。 |
cd |
可以;不带参数时返回主目录。 |
cd .. |
可以;当前目录的父目录正是主目录。 |
练习:解析相对路径
假设 pwd 显示 /Users/thing。根据下图,ls -F ../backup 会显示什么?
../backup: No such file or directory2012-12-01 2013-01-08 2013-01-272012-12-01/ 2013-01-08/ 2013-01-27/original/ pnas_final/ pnas_sub/
答案是 4。/Users 中确实有 backup;.. 先回到 /Users,再进入其中的 backup。选项 2、3 指的是 /Users/thing/backup 的内容,少考虑了向上一级。
练习:读懂 ls
假设 pwd 显示 /Users/backup,-r 表示反转列表顺序。哪些命令会得到下面的输出?
pnas_sub/ pnas_final/ original/
ls pwdls -r -Fls -r -F /Users/backup
答案是 2、3。ls pwd 会把 pwd 当作要列出的文件或目录名,不能用来代入 pwd 命令的输出。选项 2 列出当前目录,选项 3 则明确写出绝对路径。
Shell 命令的一般结构
现在我们已遇到命令、选项和参数,可以正式区分它们。例如:
$ ls -F /
这里 ls 是命令,-F 是选项,/ 是参数。短选项以单个 - 开头,长选项通常以两个 -- 开头。选项改变命令行为,参数告诉命令处理什么对象,例如哪个文件或目录。两者有时统称 parameters。
命令可以同时接受多个选项和多个参数,也可能不需要任何选项或参数。不带值的选项有时称为 switch 或 flag,本课程统一使用“选项”。
各部分用空格分开。若把 ls -F 写成 ls-F,Shell 会查找名为 ls-F 的命令。大小写也有意义:ls -s 显示各条目占用的存储块数;ls -S 按大小排序。
$ cd ~/Desktop/shell-lesson-data
$ ls -s exercise-data
示例输出:
total 28
4 animal-counts 4 creatures 12 numbers.txt 4 alkanes 4 writing
ls -s 使用块作为单位。不同系统对块的定义可能不同,不应要求数值与示例一致。
$ ls -S exercise-data
示例输出:
animal-counts creatures alkanes writing numbers.txt
把各部分合起来,ls -F / 会列出根目录内容并标注条目类型:
$ ls -F /
一种可能的输出:
Applications/ System/
Library/ Users/
Network/ Volumes/
Nelle 的工作流程:组织文件与补全
了解这些概念之后,Nelle 准备组织蛋白质测定仪产生的数据。她创建名为 north-pacific-gyre 的目录,提醒自己数据来自哪里,同时存放测定数据和处理脚本。
每个样本都按实验室约定有唯一的十字符编号,例如 NENE01729A。采样日志用这个编号对应位置、时间、深度等信息,因此她把编号也用于数据文件名。测定数据是纯文本,文件命名为 NENE01729A.txt、NENE01812A.txt 等,1520 个文件放在同一目录。
在 shell-lesson-data 目录中,可用:
$ ls north-pacific-gyre/
路径较长时,可以让 Shell 自动补全。先输入:
$ ls nor
然后按 Tab,Shell 会补成:
$ ls north-pacific-gyre/
此时再按一次 Tab,可能没有变化,因为目录中有多个候选文件;连续按两次可列出候选项。
再输入小写 g 并按 Tab,示例中所有以 g 开头的文件都共享 goo 这三个字母,因此 Shell 会继续补全到:
$ ls north-pacific-gyre/goo
再按两次 Tab,可显示这几个候选:
ls north-pacific-gyre/goo
goodiff.sh goostats.sh
这就是 Tab 补全。后面许多工具也支持类似操作。它不仅减少输入,还能帮助确认文件名的准确拼写。
要点回顾
- 文件系统管理磁盘中的信息,文件保存在目录中,目录又可容纳其他目录,形成目录树。
pwd显示当前工作目录;ls [路径]列出指定对象,不带路径时列出当前目录;cd [路径]改变当前工作目录。- 选项改变命令行为,许多短选项以
-开头。 - Unix 路径用
/分隔;Windows 原生路径通常用\。Bash 环境的路径表示仍应按具体环境理解。 - 单独的
/是根目录;绝对路径从根目录开始,相对路径从当前位置开始。 .表示当前目录,..表示父目录。
来源、许可与校订
内容依据 The Carpentries 的 The Unix Shell: Navigating Files and Directories,Copyright (c) The Carpentries 及课程贡献者。教学材料按 CC BY 4.0 再利用。本版将教学正文、练习与答案译为中文,并调整排版;命令和课程示例输出保留原文,教学图保留原 SVG。校订了分页器 n/N 搜索方向与补全示例中字母 g 的大小写,不代表原作者背书。
课程许可说明另将示例程序及软件按 MIT 许可提供,除非另有说明。必要许可文本如下:
Copyright (c) The Carpentries
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
本地已核对课程命令和输出的逐字保留情况,未在本次 Windows 环境运行这些 Bash 示例。所有目录名和输出均是课程情境,不能当作当前机器的实测记录。











暂无评论内容