在 Linux 中管理文件和目录

CompTIACompTIABeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习在 Linux 命令行环境中管理文件和目录的基本技能。你将通过 mkdirrm 命令亲手实践创建和删除复杂的目录结构,以及使用 cpmv 命令复制和移动文件和目录。

此外,本实验还将详细探讨文件链接。你将使用 ln 命令创建符号链接(软链接)和硬链接,分析 inode 的底层概念,并观察当源文件被修改时,每种链接类型的不同行为。这将帮助你更深入地理解 Linux 文件系统如何组织和引用数据。

使用 mkdir, rmdir 和 rm 创建和删除目录结构

在本步骤中,你将学习如何创建和删除目录。将文件组织到分层的目录结构中是 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 目录及其子目录 piescakes

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 和 ln -s 创建文件和符号链接

在本步骤中,你将使用 vi 文本编辑器创建一个文件,然后为其创建一个符号链接。符号链接,也称为 symlink 或 soft link,是一种特殊类型的文件,它指向另一个文件或目录。它类似于其他操作系统中的快捷方式。

首先,让我们使用 vi 创建一个名为 filea 的简单文本文件。vi 是一个功能强大、面向屏幕的文本编辑器。它主要有两种模式:命令模式(Command mode)和插入模式(Insert mode)。你开始时处于命令模式,此时按键被解释为命令。要输入文本,你必须进入插入模式。

  1. 在你的终端中,它应该位于 ~/project 路径下,启动 vi 来创建文件 filea
vi filea
  1. 你的终端现在将显示 vi 编辑器的界面。要开始输入,你需要切换到插入模式。按一次 i 键。你可能会在屏幕底部看到 -- INSERT --
  2. 现在,输入以下文本:
This is filea.
  1. 要保存文件并退出 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
  • Inode 号: 查看第一列。fileafileb 的 inode 号是不同的。为什么?因为符号链接是一个单独的文件,它只存储目标文件的路径。它本身不是文件,因此它有自己的唯一 inode。

最后,让我们看看是否可以通过链接读取内容。

cat fileb

输出是 filea 的内容:

This is filea.

这是预期的行为。当你对符号链接执行像 cat 这样的操作时,系统会自动跟随链接到源文件,并对其执行操作。

使用 ln 和 Inodes 创建和分析硬链接

在本步骤中,你将创建一个硬链接,并了解它与你之前创建的符号链接有何不同。与指向文件名的指针的符号链接不同,硬链接是文件本身的另一个名称。这两个名称都直接指向磁盘上的相同数据,该数据由一个称为 inode 的唯一数字标识。

我们将继续在 ~/project 目录中使用上一步中的文件 fileafileb

首先,让我们创建一个名为 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

让我们分析一下这个输出:

  • Inode 号(第一列): 注意 fileafilec 具有 完全相同的 inode 号(例如 131075)。这是硬链接的定义特征。它们不是独立的文件;它们是两个指向磁盘上相同文件数据的不同名称。符号链接 fileb 有其自己的唯一 inode。
  • 链接计数(第二列): 查看 fileafilec 的数字。现在是 2。这个数字是 硬链接计数,它跟踪有多少个名称(硬链接)指向这个唯一的 inode。当你创建 filec 时,此 inode 的链接计数从 1 增加到 2。
  • 文件类型(权限的第一列): 请注意,filec 被列为常规文件(其权限以 - 开头),就像 filea 一样。它不像 fileb(以 l 开头)那样是特殊链接类型。

修改源文件后观察链接行为

在本步骤中,你将观察在删除并重新创建原始源文件后,符号链接和硬链接之间行为的关键差异。这将巩固你对每种链接工作方式的理解。我们将继续在 ~/project 目录中使用 fileafilebfilec

首先,让我们删除原始文件 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 的新文件。

  1. 启动 vivi filea
  2. i 进入插入模式。
  3. 输入新内容:This is the new filea.
  4. 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(移动)命令,它们是文件管理的基础。cp 命令会创建一个文件的副本,而 mv 命令则会重命名文件/目录或将其移动到另一个位置。

让我们开始清理前几个步骤中的文件,以便有一个干净的工作空间。所有命令都将在你的 ~/project 目录中运行。

rm filea fileb filec

使用 cp 复制文件

cp 命令会创建一个新的、独立的文件副本。新文件将拥有自己的 inode。

  1. 首先,使用 touch 命令创建一个简单的文件来操作。如果文件不存在,touch 会创建一个空文件。
touch source_file
  1. 现在,让我们查看它的属性,注意 inode 号(第一列)。
ls -i source_file

输出将显示此文件的唯一 inode 号。

131081 source_file
  1. 接下来,将 source_file 复制到一个名为 copied_file 的新文件中。
cp source_file copied_file
  1. 现在,列出这两个文件的属性。
ls -i source_file copied_file

你将看到它们是两个不同的文件,具有不同的 inode 号。

131082 copied_file
131081 source_file

使用 mv 移动和重命名文件

mv 命令功能多样。如果目标是同一目录中的一个新文件名,它会重命名文件。如果目标是一个目录,它会将文件移动到该目录中。当在同一文件系统内重命名或移动文件时,inode 号不会改变;该命令只是更新文件的名称或位置指针。

  1. 让我们将 source_file 重命名为 renamed_file
mv source_file renamed_file
  1. 检查新命名文件的 inode。
ls -i renamed_file

你会注意到 inode 号(例如 131081)与原始的 source_file 相同。文件本身没有改变,只有它的名称改变了。

131081 renamed_file
  1. 现在,让我们移动这个文件。首先,创建一个目标目录。
mkdir move_destination
  1. renamed_file 移动到 move_destination 目录中。
mv renamed_file move_destination/
  1. 验证文件现在是否在目录内,并再次检查其 inode。
ls -i move_destination/renamed_file

inode 号保持不变,这证实了文件被移动了,而不是被复制。

131081 move_destination/renamed_file

处理覆盖

默认情况下,许多系统会将 cp 别名为 cp -i,以防止你意外覆盖现有文件。-i 代表“交互式”(interactive)。

  1. 让我们尝试将 copied_file 复制到我们 move_destination 目录中的文件上。
cp -i copied_file move_destination/renamed_file
  1. 由于 -i 别名,系统会提示你进行确认。
cp: overwrite 'move_destination/renamed_file'?

输入 y 并按 Enter 键确认覆盖。如果你想取消,可以输入 n

总结

在本实验中,你学习了在 Linux 环境中管理文件和目录的基本命令。你练习了使用 mkdir 创建目录结构,包括用于父目录的 -p 选项,以及使用 rmdir 删除空目录和使用 rm 删除非空目录。你还使用 vi 编辑器创建了文件,并了解了文件链接的概念。

本次实验的核心是创建和分析两种类型的链接:使用 ln -s 创建的符号(软)链接和使用 ln 创建的硬链接。你通过检查 inode 并注意源文件被修改或删除时每种链接的行为,观察了它们之间的关键差异。最后,你使用 cp 命令创建文件的独立副本,并使用 mv 命令移动或重命名文件和目录,完成了对基本文件管理操作的全面概述。