单方括号 ([ ... ]) 是 test 命令的同义词。如果您查看man page for test,您将看到几乎所有(Bash 可能有一些额外的未在此提及的)各种if 开关,正如您所称的那样。都在一个容易找到的地方。
如果您使用双方括号 ([[ ... ]]),则您使用的是扩展的 Bash 测试集。这些主要与正则表达式匹配和全局匹配(如果您也有该设置,还有扩展的全局匹配)有关。为此,您必须阅读该 Bash 手册页。
您称它们为 if 开关,但这并不正确。这些是测试,实际上与if 命令无关。
if 命令仅执行您给它的命令,然后如果该命令返回退出代码0,将运行if 语句的if 部分。否则,它将运行 else 部分(如果存在)。
让我们看看这个:
rm foo.test.txt # Hope this wasn't an important file
if ls foo.test.txt
> then
> echo "This file exists"
> else
> echo "I can't find it anywhere.."
> fi
ls: foo.test.txt: No such file or directory
I can't find it anywhere..
if 语句运行ls foo.test.txt 命令,ls 命令返回非零值,因为该文件不存在。这会导致if 语句执行else 子句。
让我们再试一次...
touch foo.test.txt # Now this file exists.
if ls foo.test.txt # Same "if/else" statement as above
> then
> echo "This file exists"
> else
> echo "I can't find it anywhere.."
> fi
foo.test.txt
This file exists
这里,ls 命令返回了0 退出状态(因为文件存在并且文件存在并且可以通过ls 命令进行统计。
通常,您不应使用ls 命令来测试文件。我只是在这里使用它来显示if 语句执行命令,然后根据该命令的退出状态执行if 或else 子句。如果你想测试一个文件是否存在,你应该使用test -e命令而不是ls命令:
if test -e foo.test.txt # The same as above, but using "test" instead of "ls"
then
echo "This file exists"
else
echo "I can't find it anywhere..."
fi
如果文件存在,test -e 将返回退出状态0。否则,它将返回非零退出状态。
如果你这样做:
ls -i /bin/test /bin/[
10958 /bin/[ 10958 /bin/test
10958 是 inode。具有相同 inode 的文件是同一文件的两个不同名称。因此[ 和test 命令是软链接1。这意味着您可以使用[ 而不是test:
if [ -e foo.test.txt ]
then
echo "This file exists"
else
echo "I can't find it anywhere.."
fi
是不是很眼熟?
1. 在 Bash 中,test 和 [ 是内置的,因此当您在 BASH 中运行这些命令时,它不会运行 /bin/test 或 /bin/[。但是,它们仍然链接彼此。