简介
Linux 将文件组织在一棵从 /(根目录)开始的目录树中。每个文件和目录都有一个路径,用于描述它在目录树中的位置。学会读取和使用路径,几乎可以让之后的所有 Linux 任务都变得更简单。
在本实验中,你将创建一个小型工作区,同时学习日常终端操作中常用的命令。你将浏览目录、创建和编辑文件、复制和移动数据、查找文件、检查元数据和 inode、体验硬链接与符号链接,并使用 diff 比较文件和目录树。
探索 Linux 目录树
在本步骤中,你将确认当前位置,检查重要的顶层目录,并为实验的其余部分创建专用工作区。
pwd 命令表示「打印工作目录」。先运行它,确认终端启动时所在的位置:
pwd
结果应为 /home/labex/project。绝对路径以 / 开头,用于描述从文件系统根目录开始的位置。
列出文件系统的顶层目录:
ls /
你会看到 etc、home、tmp、usr 和 var 等标准目录。它们通常用于:
/etc存储系统范围的配置。/home存储普通用户的主目录。/tmp存储临时数据。/usr包含许多已安装的程序和共享资源。/var包含日志和缓存等会变化的数据。
-d 选项告诉 ls 描述指定的目录本身,而不是列出目录内容。-l 选项选择长格式:
ls -ld /etc /home /tmp /usr /var
每行的第一个字符是 d,表示该对象是目录。其余列包含权限、所有者、大小、时间和名称。
为本实验创建工作区。-p 选项允许 mkdir 创建缺失的父目录;如果目录已经存在,也不会报错:
mkdir -p /home/labex/project/file-ops-lab
进入该目录并确认新位置:
cd /home/labex/project/file-ops-lab
pwd
最后的输出应为 /home/labex/project/file-ops-lab。
使用绝对路径和相对路径浏览目录
在本步骤中,你将创建嵌套目录树,并使用绝对路径、相对路径和目录导航快捷方式在其中移动。
确保从实验工作区开始:
cd /home/labex/project/file-ops-lab
使用一条命令创建三个嵌套目录:
mkdir -p navigation/alpha/beta
这里的 navigation/alpha/beta 是相对路径,因为它不是以 / 开头的。Shell 会根据当前目录解析该路径。
使用绝对路径进入最深层的目录:
cd /home/labex/project/file-ops-lab/navigation/alpha/beta
pwd
特殊路径 .. 表示父目录。从 beta 移动到 alpha:
cd ..
pwd
输出应以 /navigation/alpha 结尾。cd - 命令会返回上一个工作目录:
cd -
pwd
你应已返回 beta 目录。最后,~ 表示你的主目录。将它作为路径的开头,返回实验工作区:
cd ~/project/file-ops-lab
pwd
绝对路径可以从任何位置使用。如果你已经知道当前位置,相对路径会更短。
创建目录并写入文件
在本步骤中,你将创建目录和文件,然后学习 Shell 重定向中覆盖与追加的区别。
先进入实验工作区,同时创建两个目录:
cd /home/labex/project/file-ops-lab
mkdir documents archive
如果指定的文件不存在,touch 命令会创建一个空文件:
touch documents/empty.txt
使用长格式列出该空文件:
ls -l documents/empty.txt
文件大小应为 0 字节。接下来,> 会将命令输出重定向到文件中。它会创建文件,或替换文件原有内容:
echo "Linux file practice" > documents/notes.txt
>> 运算符会追加输出,而不会删除现有内容:
echo "Paths identify each filesystem object" >> documents/notes.txt
使用 cat 显示完整文件:
cat documents/notes.txt
你应看到两行内容,顺序与写入时一致。使用 wc -l 统计行数;-l 要求 wc 统计行数:
wc -l documents/notes.txt
第一个字段应为 2。
复制、移动、重命名和删除文件
在本步骤中,你将练习文件系统对象发生变化时的四种常见操作:复制、移动、重命名和删除。
返回实验工作区:
cd /home/labex/project/file-ops-lab
cp 命令会将源对象复制到目标位置。将 notes.txt 复制到 archive,并使用新名称:
cp documents/notes.txt archive/notes-backup.txt
确认源文件和副本都存在:
ls -l documents/notes.txt archive/notes-backup.txt
创建一个临时文件,然后使用 mv 在一次操作中移动并重命名它:
echo "draft" > documents/draft.txt
mv documents/draft.txt archive/final-draft.txt
旧路径不应再存在,而新路径应存在:
ls -l archive/final-draft.txt
要复制目录及其全部内容,请使用递归选项 -r:
cp -r documents archive/documents-copy
find archive/documents-copy -maxdepth 1 -type f
rm 命令会永久删除文件;终端没有回收站。创建并删除一个不再需要的文件:
touch disposable.tmp
rm disposable.tmp
列出当前目录,确认该路径已消失:
ls
输出中不应出现 disposable.tmp。使用 rm 前,务必仔细检查路径。
查看、更新和查找文件
在本步骤中,你将创建一个多行文件,检查文件的不同部分,使用追加重定向更新文件,并按名称查找它。
返回实验工作区。Here-document 会将多行内容发送给命令,直到 Shell 遇到一行只包含所选标记的内容;这里使用的标记是 EOF:
cd /home/labex/project/file-ops-lab
cat > documents/journal.txt <<'EOF'
First entry: created a workspace
Second entry: practiced paths
Third entry: copied files
EOF
为 'EOF' 加引号可以防止 Shell 展开文档中的特殊字符。使用行号显示文件:
nl -ba documents/journal.txt
-ba 选项会为所有行编号。使用 head -n 2 查看前两行,使用 tail -n 1 查看最后一行:
head -n 2 documents/journal.txt
tail -n 1 documents/journal.txt
追加第四条记录。前面使用过 >>;它会将输出添加到末尾,不会替换已有的三行内容:
echo "Fourth entry: reviewed the results" >> documents/journal.txt
检查结果:
tail -n 2 documents/journal.txt
现在搜索工作区中的文本文件。在 find 中,. 表示当前目录,-type f 将结果限制为普通文件,-name 用于匹配文件名模式。加引号可以防止 Shell 在 find 接收到 *.txt 之前展开它:
find . -type f -name "*.txt"
输出应包含 ./documents/journal.txt,以及你创建的其他文本文件。
检查文件类型、元数据和 inode
在本步骤中,你将超越文件名本身,检查 Linux 存储的文件系统对象信息。
先进入实验工作区,然后让 file 识别两个不同的对象:
cd /home/labex/project/file-ops-lab
file documents/journal.txt /bin/ls
journal.txt 应被识别为文本文件,而 /bin/ls 应被识别为可执行程序。Linux 并不只依靠文件扩展名来识别数据。
stat 命令会显示大小、权限、所有者、时间戳和 inode 编号等元数据:
stat documents/journal.txt
inode 是文件系统中的一条记录,用于存储文件元数据并指向文件数据。文件名是目录项,它引用某个 inode。使用自定义的 stat 格式显示稳定字段:
stat -c 'name=%n type=%F size=%s inode=%i links=%h' documents/journal.txt
%i 字段表示 inode 编号,%h 表示引用该 inode 的硬链接数量。
ls 的 -i 选项也会显示 inode 编号。创建一个用于练习元数据的文件并检查它:
echo "inode practice" > metadata-sample.txt
ls -li metadata-sample.txt
行首的数字就是 inode 编号。不同环境中的编号可能不同,因此应关注该字段代表什么,而不是记住具体数值。
使用硬链接和符号链接
在本步骤中,你将创建 Linux 中的两种链接,并观察删除原始文件名后它们各自的行为。
创建实验所需的目录和源文件:
cd /home/labex/project/file-ops-lab
mkdir links
echo "shared inode data" > links/source.txt
不带选项的 ln 命令会创建硬链接。两个名称引用同一个 inode 和文件数据:
ln links/source.txt links/hard-link.txt
-s 选项会创建符号链接,有时也称为 symlink。符号链接存储的是指向另一个文件的路径:
ln -s source.txt links/symbolic-link.txt
比较 inode 编号和链接信息:
ls -li links
source.txt 和 hard-link.txt 应具有相同的 inode 编号。符号链接拥有自己的 inode,并显示 -> source.txt。
使用 readlink 显示符号链接内部存储的路径:
readlink links/symbolic-link.txt
删除原始文件名:
rm links/source.txt
硬链接仍然可以访问该 inode 及其数据:
cat links/hard-link.txt
符号链接现在指向一个不再存在的名称。尝试读取它:
cat links/symbolic-link.txt
预期会出现 No such file or directory 错误。这一结果说明:链接对象本身仍然存在,但其中存储的目标路径已经失效。这个实验表明,只要还有另一个硬链接存在,删除其中一个硬链接名称并不会删除数据;而符号链接依赖其存储的目标路径。
使用 Diff 比较文件和目录
在本步骤中,你将使用 diff 查找差异,然后同步两个小型目录树。
创建两个版本目录:
cd /home/labex/project/file-ops-lab
mkdir -p comparison/version-a comparison/version-b
创建只有一行不同的配置文件:
printf 'mode=production\nport=8080\n' > comparison/version-a/app.conf
printf 'mode=production\nport=9090\n' > comparison/version-b/app.conf
-u 选项要求 diff 以统一格式显示差异,并在每处变化附近显示上下文:
diff -u comparison/version-a/app.conf comparison/version-b/app.conf
diff 使用 - 标记第一个文件中的行,使用 + 标记第二个文件中的行。其非零退出状态表示两个文件不同;这是预期现象。
让第二个文件与第一个文件一致,然后使用 -q 进行静默相等性检查:
cp comparison/version-a/app.conf comparison/version-b/app.conf
diff -q comparison/version-a/app.conf comparison/version-b/app.conf
没有输出表示两个文件内容一致。现在只在一个目录中添加文件:
echo "release notes" > comparison/version-a/README.txt
-r 选项会递归比较目录树:
diff -r comparison/version-a comparison/version-b
输出会报告 README.txt 只存在于 version-a 中。复制该文件,然后再次比较:
cp comparison/version-a/README.txt comparison/version-b/README.txt
diff -r comparison/version-a comparison/version-b
最后一条命令应没有输出,这证明两个目录树现在包含相同的文件内容。
总结
你练习了 Linux 终端操作中使用的核心文件和目录命令。你使用绝对路径和相对路径浏览目录,创建和编辑文件,复制和移动数据,安全地删除不再需要的文件,并按文件名搜索文件。
你还检查了文件类型和元数据,了解了文件名与 inode 的关系,比较了硬链接和符号链接,并使用 diff 比较单个文件和完整目录树。这些概念将帮助你理解 Linux 文件的工作方式,而不是把命令当作彼此孤立的操作步骤。



