介绍
在本实验中,你将在 RHEL 环境中使用基本的命令行工具,获得管理文件和目录的实践经验。你将学习如何使用 pwd 和 ls 来探索当前位置和列出内容,使用 cd 和 touch 来导航目录和创建文件,以及使用 mkdir、cp、mv 和 rm 来有效地组织文件和目录。
此外,你还将了解如何使用 ln(包括硬链接和符号链接)在文件之间创建链接,以及如何使用 shell 扩展来高效地选择文件,从而为你掌握命令行文件管理的基础技能。
使用 pwd 和 ls 命令探索当前位置并列出内容
在此步骤中,你将学习如何使用 pwd 和 ls 命令来探索文件系统中的当前位置并列出其内容。了解当前工作目录以及查看其内容是使用命令行进行文件导航和管理的基本技能。
首先,让我们使用 pwd 命令确定你的当前工作目录。pwd 代表“print working directory”(打印工作目录),它会显示你在文件系统中的当前位置的完整路径名。
pwd
你应该会看到类似以下的输出,指示你的当前目录:
/home/labex
接下来,你将使用 ls 命令列出当前目录的内容。ls 代表“list”(列出),它会列出指定目录的内容,或者在未指定目录时列出当前工作目录的内容。
ls
你应该会看到显示你的主目录内容的输出:
project
ls 命令有几个有用的选项,可以显示有关文件和目录的更多信息。
-l选项(长列表格式)提供有关每个文件和目录的详细信息,包括权限、硬链接数、所有者、组、大小和最后修改时间。ls -l你应该会看到类似以下的输出:
total 0 drwxr-xr-x 2 labex labex 6 Aug 27 2024 project-a选项(所有文件)会列出所有文件,包括隐藏文件。在 Linux 中,以点 (.) 开头的文件名被视为隐藏文件。此外,.指代当前目录,..指代父目录。ls -a你应该会看到类似以下的输出,包括隐藏的配置文件:
. .. .bash_history .bash_logout .bash_profile .bashrc .tmux.conf project将
-l和-a合并为-la,可以获得所有文件(包括隐藏文件)的长列表。ls -la这将显示所有文件和目录的详细信息,包括隐藏文件:
total 20 drwx------ 1 labex labex 72 Jun 4 03:12 . drwxr-xr-x 1 root root 19 Aug 27 2024 .. -rw------- 1 labex labex 31 Jun 4 03:13 .bash_history -rw-r--r-- 1 labex labex 18 Feb 15 2024 .bash_logout -rw-r--r-- 1 labex labex 141 Feb 15 2024 .bash_profile -rw-r--r-- 1 labex labex 877 Jun 4 03:12 .bashrc -rw-r--r-- 1 labex labex 68 Aug 27 2024 .tmux.conf drwxr-xr-x 2 labex labex 6 Aug 27 2024 project-R选项(递归)会递归地列出所有子目录的内容。为了演示这一点,我们首先创建一个子目录。mkdir mydir现在,使用
ls -R查看递归列表。ls -R你应该会看到
mydir和project目录及其内容被列出:.: mydir project ./mydir: ./project:最后,让我们删除
mydir目录,以便为后续步骤清理环境。rmdir mydir此命令仅适用于空目录。你将在后续步骤中了解更多关于
rmdir和rm的信息。

使用 cd 和 touch 命令导航目录和创建文件
在此步骤中,你将学习如何使用 cd 命令更改当前工作目录,以及使用 touch 命令创建空文件。这些命令对于高效地组织文件和在文件系统中导航至关重要。
首先,让我们验证你的当前位置,并导航到步骤 1 中显示的 project 目录。
pwd
你应该会看到 /home/labex 作为输出(你的主目录)。
现在,让我们使用 cd 命令导航到 project 目录:
cd project
验证你的新位置:
pwd
你现在应该看到 /home/labex/project 作为输出。
现在,让我们在当前 project 目录中创建一个名为 documents 的新目录。你将使用 mkdir 命令,该命令在上一
步中已简要提及。
mkdir documents
验证 documents 目录是否已创建:
ls
你应该会在输出中看到 documents。
接下来,你将使用 cd 命令将 shell 的当前工作目录更改为新创建的 documents 目录。
cd documents
更改目录后,使用 pwd 确认你的新位置是一个好习惯:
pwd
输出现在应该是 /home/labex/project/documents。
cd 命令提供了几个方便的导航选项:
cd -:此命令会切换到你之前所在的目录。让我们试试。cd -你应该会回到
/home/labex/project。使用pwd进行验证:pwd现在,再次使用
cd -返回到/home/labex/project/documents:cd -并使用
pwd进行验证:pwdcd ..:此命令使用..(两个点)隐藏目录向上移动一个级别到父目录,而无需知道确切的父目录名称。cd ..你现在应该在
/home/labex/project中。使用pwd进行验证:pwd你可以链接
..来向上移动多个级别。例如,要从/home/labex/project进入/home/labex:cd ../验证你的位置:
pwd你应该在
/home/labex中。cd(不带任何参数):此命令将始终带你回到你的主目录,对于labex用户来说,这是/home/labex。cd验证你的位置:
pwd你应该在
/home/labex中。
现在,让我们导航回你的 ~/project/documents 目录以创建一些文件。
cd ~/project/documents
验证你的位置:
pwd
输出应该是 /home/labex/project/documents。
你现在将使用 touch 命令。touch 命令会更新文件的 timestamp 为当前日期和时间,而不会修改其他任何内容。此命令对于创建空文件也非常有用。
让我们在 ~/project/documents 目录中创建两个名为 report.txt 和 notes.txt 的空文件。
touch report.txt notes.txt
使用 ls -l 验证文件是否已创建:
ls -l
你应该会看到类似以下的输出,显示新创建的文件:
total 0
-rw-rw-r--. 1 labex labex 0 Mar 7 HH:MM report.txt
-rw-rw-r--. 1 labex labex 0 Mar 7 HH:MM notes.txt
最后,让我们在 ~/project/documents 中创建一个名为 drafts 的新目录,然后在其内部创建一个文件。
mkdir drafts
cd drafts
touch draft_v1.txt
验证文件创建:
ls -l
你应该会看到 draft_v1.txt 被列出。
现在,使用一个 cd 命令导航回你的 ~/project 目录。
cd ~/project
验证你的位置:
pwd
输出应该是 /home/labex/project。
使用 mkdir、cp、mv 和 rm 命令组织文件和目录
在此步骤中,你将学习如何使用 mkdir(创建目录)、cp(复制)、mv(移动/重命名)和 rm(删除)命令来有效地组织文件和目录。这些命令对于维护一个干净且结构化的文件系统至关重要。
首先,确保你位于 ~/project 目录中。
cd ~/project
验证你的当前位置:
pwd
输出应该是 /home/labex/project。
mkdir: 创建目录
你已经使用 mkdir 创建过单个目录。现在,让我们探索更高级的 mkdir 选项。
你可以通过将多个目录作为参数列出,一次创建多个目录:
mkdir reports presentations
验证它们的创建:
ls
你应该会看到 documents、presentations 和 reports 被列出。
mkdir 命令的 -p(parents,父目录)选项对于创建目标目录所需的任何缺失的父目录非常有用。这可以防止在你尝试在不存在的父目录中创建子目录时出错。
让我们创建一个嵌套的目录结构:projects/alpha/docs。
mkdir -p projects/alpha/docs
现在,使用 ls -R 查看新创建的嵌套结构:
ls -R projects
你应该会看到:
projects:
alpha
projects/alpha:
docs
projects/alpha/docs:
cp: 复制文件和目录
cp 命令用于复制文件和目录。复制文件时,它会在当前目录或指定的其他目录中创建一个副本。
让我们将 documents 中的 report.txt 复制到 reports 目录。
cp documents/report.txt reports/
通过列出 reports 目录的内容来验证复制:
ls reports
你应该会在 reports 目录中看到 report.txt。
如果目标目录中存在同名文件,cp 默认会覆盖它。
要复制目录及其内容,你必须使用 -r(recursive,递归)选项。默认情况下,如果未指定 -r,cp 会忽略目录。
让我们将整个 documents 目录复制到 projects/alpha/ 中。
cp -r documents projects/alpha/
验证递归复制:
ls -R projects/alpha/documents
你应该会看到 documents 目录的内容(包括 notes.txt、drafts 和 drafts/draft_v1.txt)现在已复制到 projects/alpha/documents 中。
projects/alpha/documents:
drafts notes.txt report.txt
projects/alpha/documents/drafts:
draft_v1.txt
mv: 移动和重命名文件和目录
mv 命令将文件从一个位置移动到另一个位置。它还可以用于重命名文件或目录。如果你将文件的绝对路径视为其完整名称,那么移动文件实际上与重命名文件相同。移动文件的内容保持不变。
让我们将 documents 目录中的 notes.txt 重命名为 meeting_notes.txt。
mv documents/notes.txt documents/meeting_notes.txt
验证重命名:
ls documents
你现在应该看到 meeting_notes.txt 而不是 notes.txt。
现在,让我们将 reports 目录中的 report.txt 移动到 documents/drafts 中。
mv reports/report.txt documents/drafts/
验证移动:
ls reports
reports 目录现在应该是空的。
ls documents/drafts
你应该会在 documents/drafts 目录中看到 draft_v1.txt 和 report.txt。
mv 的 -v 选项会显示命令操作的详细输出,这有助于确认。
mv -v documents/meeting_notes.txt documents/final_notes.txt
你将看到类似以下的输出:
renamed 'documents/meeting_notes.txt' -> 'documents/final_notes.txt'
rm: 删除文件和目录
rm 命令用于删除文件。请小心使用 rm,因为删除的文件通常无法从命令行恢复。
让我们创建一个临时文件来练习 rm。
touch temp_file.txt
现在,删除 temp_file.txt:
rm temp_file.txt
验证其删除:
ls
temp_file.txt 应该不再被列出。
默认情况下,rm 不会删除目录。如果你尝试在没有正确选项的情况下删除非空目录,你将收到一个错误。
rm presentations
你将看到一个错误:
rm: cannot remove 'presentations': Is a directory
要删除目录及其内容,你必须使用 -r(recursive,递归)选项。rm -r 命令会先遍历每个子目录,单独删除其文件,然后再删除每个目录。
让我们删除 presentations 目录及其内容(目前是空的,但目录仍需要 -r)。
rm -r presentations
验证其删除:
ls
presentations 应该不再被列出。
rm 的 -i 选项会在删除每个文件之前交互式地提示用户确认。这是一个很好的安全措施。
让我们创建几个临时文件,然后交互式地删除它们。
touch file1.txt file2.txt
rm -i file1.txt file2.txt
你将为每个文件收到提示:
rm: remove regular empty file 'file1.txt'? y
rm: remove regular empty file 'file2.txt'? y
为每个提示输入 y 并按 Enter 以确认删除。
-f 选项(force,强制)会强制删除而不提示用户确认。如果你同时指定了 -i 和 -f,则 -f 具有优先权。请极其谨慎地使用 -f。
最后,让我们清理 projects 目录。
rm -r projects
验证 projects 是否已消失:
ls
rmdir: 删除空目录
你也可以使用 rmdir 命令来删除空目录。如果目录非空,它将失败。
让我们创建一个空目录并使用 rmdir 删除它。
mkdir empty_dir
rmdir empty_dir
验证其删除:
ls
empty_dir 应该不再被列出。
如果你尝试使用 rmdir 删除非空目录,它将失败:
mkdir test_dir
touch test_dir/test_file.txt
rmdir test_dir
你将看到一个错误:
rmdir: failed to remove 'test_dir': Directory not empty
请记住,对于非空目录,请使用 rm -r。
rm -r test_dir
使用 ln 命令(硬链接和符号链接)创建文件之间的链接
在此步骤中,你将学习如何使用 ln 命令创建文件之间的链接。Linux 文件系统支持两种类型的链接:硬链接和符号链接(或软链接)。理解它们之间的区别对于有效的文件管理至关重要。
首先,确保你位于 ~/project 目录中。
cd ~/project
验证你的当前位置:
pwd
输出应该是 /home/labex/project。
让我们创建一个名为 original_file.txt 的新文件,并包含一些内容供我们使用。
echo "This is the content of the original file." > original_file.txt
验证文件内容:
cat original_file.txt
硬链接 (Hard Links)
硬链接本质上是现有文件的另一个名称。它直接指向存储设备上与原始文件相同的数据(inode)。创建硬链接后,你无法区分新的硬链接和文件的原始名称;它们是访问相同数据的同等有效的方式。
你可以使用 ls -l 命令来确定一个文件是否具有多个硬链接。ls -l 输出中的第二列显示了文件的硬链接数量。
最初,original_file.txt 有一个硬链接(它本身):
ls -l original_file.txt
你应该会看到类似以下的输出,其中数字 1 表示一个硬链接:
-rw-rw-r--. 1 labex labex 35 Mar 7 HH:MM original_file.txt
现在,让我们使用 ln 命令创建一个名为 hard_link.txt 的硬链接到 original_file.txt。
ln original_file.txt hard_link.txt
检查两个文件的硬链接计数:
ls -l original_file.txt hard_link.txt
你现在应该看到两个文件的硬链接计数都为 2,这表明它们指向相同的数据:
-rw-rw-r--. 2 labex labex 35 Mar 7 HH:MM hard_link.txt
-rw-rw-r--. 2 labex labex 35 Mar 7 HH:MM original_file.txt
为了确认它们指向相同的数据,你可以使用 ls -i 选项来列出每个文件的 inode 号。如果文件位于同一文件系统上且它们的 inode 号相同,那么这些文件就是指向相同数据文件内容的硬链接。
ls -i original_file.txt hard_link.txt
inode 号应该是相同的:
1234567 original_file.txt 1234567 hard_link.txt
如果你修改其中一个文件的内容,更改将反映在另一个文件中,因为它们是相同的基础数据。
echo "Adding new line." >> hard_link.txt
cat original_file.txt
你将看到:
This is the content of the original file.
Adding new line.
即使原始文件被删除,只要至少存在一个其他硬链接,你仍然可以访问该文件的内容。数据仅在最后一个硬链接被删除时才从存储中删除,使得文件内容不再被任何硬链接引用。
让我们删除 original_file.txt:
rm original_file.txt
现在,尝试访问 hard_link.txt:
cat hard_link.txt
你仍然会看到内容:
This is the content of the original file.
Adding new line.
hard_link.txt 的硬链接计数现在应该为 1:
ls -l hard_link.txt
硬链接的限制:
- 你只能对常规文件使用硬链接。你不能使用
ln命令创建指向目录或特殊文件的硬链接。 - 你只能在两个文件位于同一文件系统上时使用硬链接。你可以使用
df命令列出文件系统。
符号链接 (Symbolic Links)
符号链接(也称为“软链接”或“symlink”)是一种特殊类型的文件,它通过其路径指向另一个文件或目录。它类似于 Windows 中的快捷方式。与硬链接不同,符号链接不直接指向数据;它们指向目标文件或目录的名称。
让我们创建一个名为 target_file.txt 的新文件作为我们的符号链接。
echo "This is the target file for the symbolic link." > target_file.txt
现在,使用 ln -s 命令创建一个名为 sym_link.txt 的符号链接,指向 target_file.txt。
ln -s target_file.txt sym_link.txt
使用 ls -l 检查符号链接的详细信息:
ls -l target_file.txt sym_link.txt
你会注意到几点不同:
sym_link.txt的长列表的第一个字符是l(字母l),表示它是一个符号链接。- 输出显示
sym_link.txt -> target_file.txt,明确显示了它指向的内容。 - 符号链接的大小非常小(只是目标路径的长度),而不是目标文件的大小。
sym_link.txt的硬链接计数为1。
-rw-rw-r--. 1 labex labex 45 Mar 7 HH:MM target_file.txt
lrwxrwxrwx. 1 labex labex 14 Mar 7 HH:MM sym_link.txt -> target_file.txt
你可以通过 sym_link.txt 访问 target_file.txt 的内容:
cat sym_link.txt
你将看到:
This is the target file for the symbolic link.
符号链接的关键区别和行为:
跨文件系统链接: 符号链接可以链接不同文件系统上的两个文件。
链接到目录: 符号链接可以指向目录,而不仅仅是常规文件。让我们创建一个指向你的
documents目录的符号链接。ln -s documents doc_shortcut现在,你可以像
documents目录本身一样cd进入doc_shortcut:cd doc_shortcut验证你的位置。请注意,
pwd默认显示符号链接的路径:pwd输出:
/home/labex/project/doc_shortcut如果你希望
pwd显示符号链接指向的目录的实际路径,请使用-P选项:pwd -P输出:
/home/labex/project/documents现在,返回到
~/project:cd ~/project悬空符号链接 (Dangling symbolic links): 当原始常规文件(目标)被删除时,符号链接仍然存在,但指向一个丢失的文件。这被称为“悬空符号链接”。
让我们删除
target_file.txt:rm target_file.txt现在,使用
ls -l检查sym_link.txt:ls -l sym_link.txt你会看到
sym_link.txt仍然存在,但其目标target_file.txt以红色或其他颜色显示(取决于你的终端配置),以表明它已损坏:lrwxrwxrwx. 1 labex labex 14 Mar 7 HH:MM sym_link.txt -> target_file.txt如果你尝试
cat悬空符号链接,它将失败:cat sym_link.txt输出:
cat: sym_link.txt: No such file or directory
最后,让我们清理此步骤中创建的文件和链接。
rm hard_link.txt sym_link.txt doc_shortcut
ls
从之前的步骤来看,你应该只剩下 documents 和 reports 目录。
使用 Shell 扩展高效选择文件
在这一步中,你将学习如何使用各种 Shell 扩展特性高效地选择文件和目录,包括模式匹配(Globbing)、波浪号扩展(Tilde Expansion)、花括号扩展(Brace Expansion)、变量扩展(Variable Expansion)和命令替换(Command Substitution)。这些特性允许你使用简洁的命令对多个文件执行操作。
首先,确保你位于 ~/project 目录下。
cd ~/project
验证你当前的位置:
pwd
输出应为 /home/labex/project。
为了演示 Shell 扩展,让我们创建一组文件和目录。
mkdir data
cd data
touch file1.txt file2.log file_a.txt file_b.log report_2023.txt report_2024.log
touch image.jpg document.pdf archive.zip
mkdir dir1 dir2 dir3
cd ..
现在,列出 data 目录的内容,查看你创建的文件:
ls data
你应该看到:
archive.zip dir1 dir2 dir3 document.pdf file1.txt file2.log file_a.txt file_b.log image.jpg report_2023.txt report_2024.log
模式匹配(Globbing)
模式匹配,也称为 globbing,允许你根据模式使用称为元字符(metacharacters)的特殊字符来选择文件。
| 元字符 | 匹配内容 | 示例 |
|---|---|---|
* |
零个或多个字符的任意字符串。 | *.txt 匹配所有以 .txt 结尾的文件。 |
? |
任意单个字符。 | file?.txt 匹配 file1.txt、fileA.txt 等。 |
[abc...] |
方括号内任意一个字符。 | file[12].txt 匹配 file1.txt 或 file2.txt。 |
[!abc...] |
方括号内除指定字符外的任意一个字符。 | file[!1].txt 匹配 fileA.txt 但不匹配 file1.txt。 |
[[:alpha:]] |
任意字母字符。 | file[[:alpha:]].txt 匹配 fileA.txt。 |
[[:digit:]] |
任意单个数字(0 到 9)。 | file[[:digit:]].txt 匹配 file1.txt。 |
让我们在 data 目录中尝试一些示例。
使用
*: 列出所有以.txt结尾的文件:ls data/*.txt输出:
data/file1.txt data/file_a.txt data/report_2023.txt列出所有名称中包含
file的文件:ls data/*file*输出:
data/file1.txt data/file2.log data/file_a.txt data/file_b.log使用
?: 列出.log前恰好有一个字符的文件:ls data/file?.log输出:
data/file2.log使用
[]进行字符集匹配: 列出以report_开头,名称中包含2023或2024的文件:ls data/report_[2][0][2][34].*输出:
data/report_2023.txt data/report_2024.log使用
{}进行花括号扩展: 列出以file开头,并以.txt或.log结尾的文件:ls data/file*.{txt,log}输出:
data/file1.txt data/file2.log data/file_a.txt data/file_b.log
波浪号扩展 ~
波浪号(~)字符扩展为当前用户的家目录(/home/labex)。如果后面跟用户名,它将扩展为该用户的家目录。
echo ~
输出:
/home/labex
echo ~root
输出:
/root
echo ~/project/data
输出:
/home/labex/project/data
花括号扩展 {}
花括号扩展用于生成任意字符串。它对于创建具有相似名称的文件或目录列表非常有用,而无需单独输入每个名称。
逗号分隔列表: 创建文件
report_jan.txt、report_feb.txt、report_mar.txt:touch data/report_{jan,feb,mar}.txt列出它们:
ls data/report_*.txt输出:
data/report_2023.txt data/report_jan.txt data/report_feb.txt data/report_mar.txt数字或字母范围: 创建文件
doc1.txt、doc2.txt、doc3.txt:touch data/doc{1..3}.txt列出它们:
ls data/doc*.txt输出:
data/doc1.txt data/doc2.txt data/doc3.txt创建目录
chapterA、chapterB、chapterC:mkdir data/chapter{A..C}列出它们:
ls data/chapter*输出:
data/chapterA data/chapterB data/chapterC
变量扩展
Shell 变量存储值,这些值可以在命令中扩展。你使用 VARNAME=value 定义一个变量,并使用 $VARNAME 或 ${VARNAME} 访问其值。
MY_DIR=data
echo "My directory is: $MY_DIR"
输出:
My directory is: data
你可以在命令中使用变量:
ls $MY_DIR
输出将是 data 目录的内容。
命令替换
命令替换允许你将一个命令的输出用作另一个命令的一部分。这通过将命令用 $(command) 或反引号 `command` 包围来实现。$(command) 语法通常更受青睐,因为它支持嵌套。
让我们获取当前日期并将其用于文件名中。
touch data/log_$(date +%Y-%m-%d).txt
列出 data 目录以查看新文件:
ls data/log_*.txt
输出将类似于:
data/log_2024-03-07.txt
你也可以用它来计算文件数量:
echo "There are $(ls data | wc -l) items in the data directory."
输出将类似于:
There are 19 items in the data directory.
保护参数免受扩展影响
有时,你希望阻止 Shell 扩展某些字符。你可以通过以下方式实现:
反斜杠(
\): 转义紧随其后的单个字符。echo "The value of \$HOME is your home directory."输出:
The value of $HOME is your home directory.单引号(
''): 阻止引号内的所有 Shell 扩展。echo 'The current date is $(date +%Y-%m-%d).'输出:
The current date is $(date +%Y-%m-%d).双引号(
""): 阻止大多数 Shell 扩展,但允许变量扩展($VAR)和命令替换($())。MY_DATE=$(date +%Y-%m-%d) echo "Today's date is $MY_DATE."输出:
Today's date is 2024-03-07.与单引号进行比较:
echo 'Today is $MY_DATE.'输出:
Today's date is $MY_DATE.
最后,让我们清理 data 目录。
rm -r data
总结
在此次实验中,你学习了 RHEL 中用于管理文件和目录的基本命令行工具。你首先掌握了 pwd 命令来识别你当前的工作目录,以及 ls 命令来列出目录内容,包括使用 -l 选项获取详细信息和使用 -a 选项显示隐藏文件。然后,你使用 cd 命令导航文件系统,并使用 touch 命令创建新文件。
此外,你还熟练掌握了使用 mkdir 创建目录、使用 cp 复制文件和目录、使用 mv 移动或重命名它们以及使用 rm 删除它们来组织文件系统。本次实验还涵盖了使用 ln 创建硬链接和符号链接,以及如何使用 Shell 扩展高效地选择文件,从而增强了你从命令行有效管理文件和目录的能力。



