介绍
在本实验中,你将学习在 Linux 命令行环境中管理文件和目录的基本技能。你将通过 mkdir
和 rm
命令亲手实践创建和删除复杂的目录结构,以及使用 cp
和 mv
命令复制和移动文件和目录。
此外,本实验还将详细探讨文件链接。你将使用 ln
命令创建符号链接(软链接)和硬链接,分析 inode 的底层概念,并观察当源文件被修改时,每种链接类型的不同行为。这将帮助你更深入地理解 Linux 文件系统如何组织和引用数据。
在本实验中,你将学习在 Linux 命令行环境中管理文件和目录的基本技能。你将通过 mkdir
和 rm
命令亲手实践创建和删除复杂的目录结构,以及使用 cp
和 mv
命令复制和移动文件和目录。
此外,本实验还将详细探讨文件链接。你将使用 ln
命令创建符号链接(软链接)和硬链接,分析 inode 的底层概念,并观察当源文件被修改时,每种链接类型的不同行为。这将帮助你更深入地理解 Linux 文件系统如何组织和引用数据。
在本步骤中,你将学习如何创建和删除目录。将文件组织到分层的目录结构中是 Linux 中的一项基本任务。我们将使用 mkdir
命令创建目录,rmdir
删除空目录,以及 rm
删除目录及其所有内容。所有命令都将从你的默认目录 ~/project
执行。
首先,让我们创建一个简单的目录。mkdir
命令代表“make directory”(创建目录)。
在你的终端中,执行以下命令创建一个名为 cars
的目录:
mkdir cars
要验证目录是否已创建,你可以使用 ls -ld
命令。-l
选项提供长列表格式,而 -d
选项列出目录条目本身,而不是其内容。
ls -ld cars
你应该会看到类似以下的输出,确认 cars
目录已创建。权限字符串开头的 d
表示它是一个目录。
drwxr-xr-x 2 labex labex 4096 May 20 10:30 cars
现在,让我们删除这个目录。rmdir
命令用于删除 空 目录。
rmdir cars
再次运行 ls -ld
命令来验证其删除。
ls -ld cars
这次,你将收到一个错误消息,因为该目录已不存在。这证实了 rmdir
操作成功。
ls: cannot access 'cars': No such file or directory
rmdir
命令只能处理空目录。如果有一个嵌套目录结构怎么办?让我们尝试创建一个目录结构 pastry/pies/cakes
。要按需创建父目录,我们必须在 mkdir
中使用 -p
(parents,父目录)选项。
执行以下命令:
mkdir -p pastry/pies/cakes
要查看你刚刚创建的整个目录结构,请使用带有 -l
(长格式)和 -R
(recursive,递归)选项的 ls
命令。
ls -lR pastry
输出将显示 pastry
目录及其子目录 pies
和 cakes
。
pastry:
total 4
drwxr-xr-x 3 labex labex 4096 May 20 10:35 pies
pastry/pies:
total 4
drwxr-xr-x 2 labex labex 4096 May 20 10:35 cakes
pastry/pies/cakes:
total 0
现在,让我们尝试使用 rmdir
删除 pastry
目录。
rmdir pastry
为什么这个命令失败了?终端会显示一个错误消息:
rmdir: failed to remove 'pastry': Directory not empty
这是因为 rmdir
只能删除空目录,而 pastry
包含 pies
子目录。
要删除目录及其所有内容(包括子目录和文件),你必须使用带有 -r
(recursive,递归)选项的 rm
命令。请非常小心使用此命令,因为它会永久删除数据。
rm -r pastry
如果成功,此命令将不会产生任何输出。你可以通过再次运行 ls -ld pastry
来验证 pastry
目录是否已被完全删除,这应该会产生一个“No such file or directory”错误。
ls -ld pastry
在本步骤中,你将使用 vi
文本编辑器创建一个文件,然后为其创建一个符号链接。符号链接,也称为 symlink 或 soft link,是一种特殊类型的文件,它指向另一个文件或目录。它类似于其他操作系统中的快捷方式。
首先,让我们使用 vi
创建一个名为 filea
的简单文本文件。vi
是一个功能强大、面向屏幕的文本编辑器。它主要有两种模式:命令模式(Command mode)和插入模式(Insert mode)。你开始时处于命令模式,此时按键被解释为命令。要输入文本,你必须进入插入模式。
~/project
路径下,启动 vi
来创建文件 filea
:vi filea
vi
编辑器的界面。要开始输入,你需要切换到插入模式。按一次 i
键。你可能会在屏幕底部看到 -- INSERT --
。This is filea.
vi
,你必须先按 Esc
键返回到命令模式。然后,输入 ZZ
(按住 Shift 键并按两次 Z)。此命令将保存文件并退出编辑器。现在你已回到命令提示符,让我们验证文件是否已创建并包含正确的内容。
首先,列出文件:
ls filea
输出应该只是文件名:
filea
接下来,使用 cat
命令显示其内容:
cat filea
输出应该与你输入的文本匹配:
This is filea.
现在,让我们创建一个符号链接。我们将创建一个名为 fileb
的链接,它指向我们的原始文件 filea
。命令格式为 ln -s <源文件> <目标链接>
。
ln -s filea fileb
要测试结果,请使用 ls -il
命令。-i
选项显示 inode 号,这是文件系统上文件或目录的唯一标识符。
ls -il file[ab]
仔细检查输出。
131075 -rw-r--r-- 1 labex labex 14 May 20 10:40 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
请注意以下几点:
filea
的权限字符串以 -
开头,表示一个常规文件。fileb
的字符串以 l
开头,表示一个符号链接。fileb -> filea
。filea
和 fileb
的 inode 号是不同的。为什么?因为符号链接是一个单独的文件,它只存储目标文件的路径。它本身不是文件,因此它有自己的唯一 inode。最后,让我们看看是否可以通过链接读取内容。
cat fileb
输出是 filea
的内容:
This is filea.
这是预期的行为。当你对符号链接执行像 cat
这样的操作时,系统会自动跟随链接到源文件,并对其执行操作。
在本步骤中,你将创建一个硬链接,并了解它与你之前创建的符号链接有何不同。与指向文件名的指针的符号链接不同,硬链接是文件本身的另一个名称。这两个名称都直接指向磁盘上的相同数据,该数据由一个称为 inode 的唯一数字标识。
我们将继续在 ~/project
目录中使用上一步中的文件 filea
和 fileb
。
首先,让我们创建一个名为 filec
的硬链接,它指向与 filea
相同的 inode。为此,我们使用 ln
命令,但 不 加 -s
选项。
ln filea filec
现在,让我们查看所有三个文件的内容:原始文件 filea
、符号链接 fileb
和新的硬链接 filec
。
cat filea
cat fileb
cat filec
你将看到相同的内容打印了三次,这是预期的。
This is filea.
This is filea.
This is filea.
当我们检查文件属性时,真正的区别就显现出来了。再次使用 ls -il
命令查看所有三个文件的 inode 号和其他详细信息。
ls -il file[a-c]
输出将类似如下。请密切关注第一列和第二列。
131075 -rw-r--r-- 2 labex labex 14 May 20 10:40 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
131075 -rw-r--r-- 2 labex labex 14 May 20 10:40 filec
让我们分析一下这个输出:
filea
和 filec
具有 完全相同的 inode 号(例如 131075
)。这是硬链接的定义特征。它们不是独立的文件;它们是两个指向磁盘上相同文件数据的不同名称。符号链接 fileb
有其自己的唯一 inode。filea
和 filec
的数字。现在是 2
。这个数字是 硬链接计数,它跟踪有多少个名称(硬链接)指向这个唯一的 inode。当你创建 filec
时,此 inode 的链接计数从 1 增加到 2。filec
被列为常规文件(其权限以 -
开头),就像 filea
一样。它不像 fileb
(以 l
开头)那样是特殊链接类型。在本步骤中,你将观察在删除并重新创建原始源文件后,符号链接和硬链接之间行为的关键差异。这将巩固你对每种链接工作方式的理解。我们将继续在 ~/project
目录中使用 filea
、fileb
和 filec
。
首先,让我们删除原始文件 filea
。
rm filea
现在,让我们检查这三个文件的状态。使用 ls -l
命令。你可能会看到 filea
的错误,因为它不再存在,这是预期的。
ls -l file[a-c]
输出将非常具有启发性:
ls: cannot access 'filea': No such file or directory
lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
-rw-r--r-- 1 labex labex 14 May 20 10:40 filec
fileb
: 该链接现在是“断开的”。它仍然指向名称 filea
,但该名称不再对应于存在的文件。在许多终端中,文件名 fileb
将显示为红色,以指示此断开状态。如果你尝试 cat fileb
,你将收到一个错误。filec
: 文件 filec
完全不受影响。它的链接计数(第二列)只是从 2 减少到 1,但文件及其数据仍然完好无损。这是因为删除 filea
只移除了指向该 inode 的一个名称;在链接计数降至零之前,数据不会被删除。你可以通过查看其内容来证明这一点:cat filec
输出仍然是原始内容:
This is filea.
现在,让我们重新创建 filea
,但使用不同的内容。使用 vi
创建一个名为 filea
的新文件。
vi
:vi filea
i
进入插入模式。This is the new filea.
Esc
返回命令模式,然后输入 ZZ
保存并退出。在新 filea
就位后,让我们再次使用 ls -il
检查所有三个文件。
ls -il file[a-c]
输出将显示一种新情况:
131080 -rw-r--r-- 1 labex labex 20 May 20 11:05 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
131075 -rw-r--r-- 1 labex labex 14 May 20 10:40 filec
filea
: 存在一个新的文件 filea
,但请注意其 inode 号(例如 131080
)与 filec
的 inode 号(例如 131075
)不同。这是一个全新的文件,碰巧与旧文件同名。fileb
: 该链接不再是断开的!它会自动指向名为 filea
的新文件。filec
: filec
保持不变。它仍然指向原始 inode 并包含原始数据。最后,让我们检查所有三个文件的内容以查看结果。
cat filea
cat fileb
cat filec
输出清楚地展示了差异:
This is the new filea.
This is the new filea.
This is filea.
符号链接 fileb
跟踪名称指向了新文件,而硬链接 filec
则保持了与原始数据的连接。
在最后这个步骤中,你将学习使用 cp
(复制)和 mv
(移动)命令,它们是文件管理的基础。cp
命令会创建一个文件的副本,而 mv
命令则会重命名文件/目录或将其移动到另一个位置。
让我们开始清理前几个步骤中的文件,以便有一个干净的工作空间。所有命令都将在你的 ~/project
目录中运行。
rm filea fileb filec
cp
复制文件cp
命令会创建一个新的、独立的文件副本。新文件将拥有自己的 inode。
touch
命令创建一个简单的文件来操作。如果文件不存在,touch
会创建一个空文件。touch source_file
ls -i source_file
输出将显示此文件的唯一 inode 号。
131081 source_file
source_file
复制到一个名为 copied_file
的新文件中。cp source_file copied_file
ls -i source_file copied_file
你将看到它们是两个不同的文件,具有不同的 inode 号。
131082 copied_file
131081 source_file
mv
移动和重命名文件mv
命令功能多样。如果目标是同一目录中的一个新文件名,它会重命名文件。如果目标是一个目录,它会将文件移动到该目录中。当在同一文件系统内重命名或移动文件时,inode 号不会改变;该命令只是更新文件的名称或位置指针。
source_file
重命名为 renamed_file
。mv source_file renamed_file
ls -i renamed_file
你会注意到 inode 号(例如 131081
)与原始的 source_file
相同。文件本身没有改变,只有它的名称改变了。
131081 renamed_file
mkdir move_destination
renamed_file
移动到 move_destination
目录中。mv renamed_file move_destination/
ls -i move_destination/renamed_file
inode 号保持不变,这证实了文件被移动了,而不是被复制。
131081 move_destination/renamed_file
默认情况下,许多系统会将 cp
别名为 cp -i
,以防止你意外覆盖现有文件。-i
代表“交互式”(interactive)。
copied_file
复制到我们 move_destination
目录中的文件上。cp -i copied_file move_destination/renamed_file
-i
别名,系统会提示你进行确认。cp: overwrite 'move_destination/renamed_file'?
输入 y
并按 Enter 键确认覆盖。如果你想取消,可以输入 n
。
在本实验中,你学习了在 Linux 环境中管理文件和目录的基本命令。你练习了使用 mkdir
创建目录结构,包括用于父目录的 -p
选项,以及使用 rmdir
删除空目录和使用 rm
删除非空目录。你还使用 vi
编辑器创建了文件,并了解了文件链接的概念。
本次实验的核心是创建和分析两种类型的链接:使用 ln -s
创建的符号(软)链接和使用 ln
创建的硬链接。你通过检查 inode 并注意源文件被修改或删除时每种链接的行为,观察了它们之间的关键差异。最后,你使用 cp
命令创建文件的独立副本,并使用 mv
命令移动或重命名文件和目录,完成了对基本文件管理操作的全面概述。