Bash非常灵活,并提供了各种测试文件的选项。如果您想要测试文件的方法,Bash文件测试操作符将带您进入。
在本教程中,您将学习不同的文件测试操作符以及如何使用它们来测试文件是否存在、是否可读、是否为空等。
继续阅读并与Bash文件测试操作符交友!
先决条件
本教程将进行实践演示。如果您想跟着做,请确保您具有以下内容:
- A Linux system with Bash installed – This tutorial uses Ubuntu 20.04.
大多数Linux发行版默认安装了Bash。但是,如果您使用Windows,您可以安装Windows子系统以获取Bash shell。
- A user account with sudo privileges to run commands as root – This tutorial uses a root account for simplicity. But using a non-root user with sudo access is always recommended.
- 本教程假设您可以访问Linux系统的SSH。
什么是 Bash 文件测试操作符?
在您开始使用测试操作符之前,先了解它们的工作原理。文件测试操作符可以让您测试文件的各个方面,比如文件是否存在、可读/可写等。
使用文件测试操作符可以帮助您避免在 Bash 脚本中出现错误。下面的代码是 if 语句的模板。if-else 语句是您经常在 Bash 脚本中看到的强大工具。
请记住,代码块的 then 和 else 部分是可选的。您可以在不使用它们的情况下使用 if 语句。
检查文件是否存在
你已经见识过测试运算符的工作原理,但这还不足以更好地理解它们的使用要点。所以,我们从一个基本示例开始,比如检查文件是否存在。
在现实世界中,你可能希望在创建配置文件之前检查其是否存在。你不想浪费时间从头开始构建一个配置文件,只是为了发现相同的文件已经存在了。
要检查文件是否已经存在:
1. 打开你的终端,并运行下面的touch命令来创建一个新的 test.txt 文件。这个命令不会提供输出,但你将在下一步中验证文件是否存在。
2. 接下来,运行以下ls命令来列出你的工作目录中新创建的文件(test.txt)。
下面的输出证实你已成功创建了test.txt文件。
现在你有了一个测试文件,你可以按照以下步骤在Bash脚本中使用样板代码块来检查文件是否存在。

3. 运行下面的命令来创建(touch)并打开一个新的shell脚本文件(if_file_exists.sh),在你喜欢的文本编辑器(nano)中。
4. 现在,将下面的代码填入你的新文件if_file_exists.sh 中,保存文件并关闭编辑器。
- 运行一个if-else语句来测试指定文件是否存在。
- 如果操作符返回true,则会收到文件存在的消息。
- 如果操作符返回true,则会收到文件不存在的消息。但是这次,文件会自动创建,采用你在FILE变量中定义的名称。
文件顶部的#!/bin/bash行被称为shebang。shebang告诉你的系统要使用哪个解释器来运行脚本,在这种情况下是Bash。如果不包括shebang,你的系统将使用默认解释器,这可能不是Bash。缺少shebang可能导致脚本执行失败。
5. 运行以下命令以执行您的新脚本(if_file_exists.sh)
如果一切顺利,您将在终端中看到打印的test.txt存在消息,如下所示。

6. 接下来,运行以下命令删除(rm -rf)测试文件(test.txt),并列出您的工作目录中的所有文件。
下面,您可以验证test.txt不再列出。

7. 重新运行下面的命令以执行您的if_file_exists.sh脚本。
由于test.txt文件不再存在,当-e运算符返回false时,脚本将创建一个新的test.txt文件。

8. 最后,运行以下ls命令以列出您工作目录中的test.txt文件。
下面的输出确认了您的脚本创建了一个新的test.txt文件。

检查文件是否为普通文件还是特殊文件
在打开或处理文件之前,您可能希望首先检查该文件是否是普通文件还是特殊文件。为什么呢?特殊文件是存储在文件系统中的一种文件类型,因此请注意不要搞乱这些文件。
例如,当打开特殊文件时常见的错误是“没有这样的文件或目录”错误。当您尝试打开的文件不存在时,会出现此错误。但是当打开特殊文件而不是普通文件时,也可能会出现相同的错误。
在您的文本编辑器中打开一个新的special_file.sh文件,添加以下代码并保存更改。
以下代码与先前的代码类似。但是这段代码使用了-f
运算符而不是-e
运算符。
现在,运行下面的命令来执行你的special_file.sh
脚本。
由于/dev/vmmon中指定的文件在FILE
变量中是一个特殊文件,你会收到下面的消息。

检查目录是否存在
到目前为止,你已经学会了如何检查文件是否存在。但是相同的方法是否适用于目录?是的,可以使用-d
测试运算符。如果你计划根据目录是否存在来采取行动,这个运算符会很方便。
也许你想将一个目录中的所有文件复制到另一个目录中。如果目标目录不存在,你可以在复制文件之前创建它。
1. 运行以下ls命令来列出工作目录中的example-dir。
由于该目录不存在,您将收到一个消息,显示找不到文件或目录。如果您不想因为目录不存在而中断流程,可以跳到下一步。

2. 接下来,在您的文本编辑器中打开一个名为if_dir_exists.sh的新文件,添加下面的代码并保存文件。以下代码测试指定目录是否存在,并根据-d运算符返回的值执行任务。
您可以通过使用否定运算符(!)来交换if和else语句的位置,从而实现相同的结果。在现实世界的情况下,!运算符可以帮助编写更清晰、更简洁的脚本。
3. 现在,运行以下命令来执行您的脚本(if_dir_exists.sh)
你可以看到消息说目录已创建,并且test.txt文件已复制,因为example_dir 不存在。

4. 最后,对example_dir 目录运行ls命令以确认目录存在并包含test.txt文件。

检查文件是否为空
你已经知道如何使用最常用的三个文件测试运算符(-e
、-f
和-d
)来提升你的脚本技能。但还有其他运算符你可能会感兴趣。
通常,你会运行一个命令而不是突出显示一个文件的内容并将其复制到另一个文件。但是要稍等,因为你的目标文件可能不为空。
为什么不使用-s
运算符来检查文件是否存在且不为空呢?该运算符在文件存在且大小大于零时返回true。
1. 在文本编辑器中打开一个名为empty_file.sh的新文件,添加以下代码,并保存文件。
以下代码测试指定文件是否为空,并根据-s运算符返回的值打印消息。
2. 现在,运行下面的命令来执行你的脚本(empty_file.sh)。
下面,你可以看到消息,说明test.txt要么不存在要么为空。但与此同时,脚本向test.txt文件添加了文本。

3. 运行下面的cat命令来验证test.txt文件是否包含了添加的文本。

4. 最后,重新运行下面的bash命令来执行empty_file.sh脚本。
下面,你可以看到输出已经更改为test.txt存在且不为空,因为test.txt文件现在包含了一些文本并且大小大于零(0)。

检查文件是否存在且可读
也许你的自动化涉及读取文件以执行任务。这些任务的成功将取决于文件是否可读。编写一个脚本来检查文件是否存在且可读将成为一个方便的解决方案。
为了演示检查文件是否存在且可读,请执行以下操作:
1. 运行以下命令以登录到另一个用户账户(ata)。
您的提示符($)会更改,指示您已登录为其他用户。

或者,您可以使用chmod命令更改文件的权限为可读、可写或两者兼有。
2. 登录后,使用您的文本编辑器创建一个名为readable_file.sh的新文件
将以下代码添加到readable_file.sh文件中,并保存更改。此代码检查/root目录中是否存在名为test.txt的文件,并且该文件是否可读。
3. 现在,运行以下命令以执行readable_file.sh脚本。
这次,您将看到一条消息,指出`/root/test.txt`不存在或不可读。由于text.test文件位于/root目录中,当前用户(ata)对text.txt文件没有读取权限。

4. 最后,运行以下命令执行以下操作:
- 更改sudoers文件,以允许当前用户(ata)使用
sudo
来运行提升的命令。
- 执行`readable_file.sh`脚本,该脚本测试特定文件是否可读。
您可以看到下面的输出打印`test.txt`存在且可读,因为ata用户现在对test.txt文件有读取权限。

结论
A testing phase is always a priority before making drastic changes, whether on files or directories on your system. And in this tutorial, you’ve learned about the Bash file test operators and how to use them to test if a file (regular or special) or directory exists or if a file is readable or not.
有了这些新发现的技能,您可以自信地根据测试结果决定采取哪种行动。但是,还有许多其他方法可以使用Bash文件测试运算符。
为什么不尝试检查文件的扩展名?或者检查多个文件是否存在,以查看您需要的所有文件是否都可用?