吹毛求疵
开关-a 和-n 严格来说不是bash if 语句的一部分,因为if 命令不处理这些开关。
什么是初选?
我称它们为“开关”,但您链接到的 bash 文档与“初级”指的是相同的东西(可能是因为这是讨论布尔表达式的一部分时使用的常用术语)。
背景和文档
在sh 脚本中if 是一个以命令为参数的命令,执行它并测试它的返回码。如果返回码是0,则执行then 之后的代码块,直到关闭fi 或(如果提供)以下else。如果返回代码不是0 并且提供了else 语句,则执行else 之后的代码块直到关闭fi。
您可以通过将if 传递给命令true 或命令false 来查看此效果,它们是不执行任何操作并分别返回0 和非0 的简单命令。
if true ; then echo true was true ; else echo true was false ; fi
if false ; then echo false was true ; else echo false was false ; fi
在您提供的示例代码中,您传递给if 的命令是[,有时也称为test。正是这个命令采用了您要询问的开关。在bash 中,test 命令将是一个内置命令;尝试type [ 了解它的类型。对于内置命令help 将显示用法,因此也运行help [ 以查看文档。您的系统可能还有/bin/[ 和/bin/test,如果您是man test,您可以查看它们的手册。尽管内置 test 的行为可能与手册页中记录的行为不同,这可能比您从 help [ 获得的简单描述更详细,但它可能会描述内置[ 命令相当准确。
-a 和 -n 的行为
知道您正在运行的命令是test,我们可以咨询help test 或man test 并阅读其用法。这将表明-n 测试以下参数,如果它不是空字符串,则计算结果为真。
在test 的文档中,您还将看到一个开关-e。如果该参数是存在的文件或目录,则此开关测试以下参数并评估为真。更有用的是-f 开关,如果以下参数存在并且是常规文件(而不是目录或块设备或其他),则该开关评估为 true。
您感到困惑的原因可能是-a 可能有两种 形式:一元和二元。当-a 在一元上下文中使用时,即有一个后面的参数但没有前面的参数,它将其参数视为一个文件并测试它的存在,只是就像-e 开关一样。但是,当-a 用于二进制上下文时,即在它之前有一个参数,在它之后有一个参数,它会将其参数视为其他条件并充当布尔 AND 运算符。 p>
为了可移植性,重要的是要注意一元 -a 是非标准扩展,在 POSIX 中 won't be found。它在bash 和ksh 中可用,但是,它的使用可能很普遍。
示例
cd /tmp
if [ -a test-file ] ; then
echo 1: test-file exists
else
echo 1: test-file missing
fi
touch test-file
if [ -a test-file ] ; then
echo 2: test-file exists
else
echo 2: test-file missing
fi
var=somerthing
if [ -n "$var" -a -a test-file ] ; then
echo variable var is not empty and test-file exists
fi
rm -f test-file