-a
和-n
选项在以下 bashif
语句中执行什么功能?
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
REFNAME=$(basename $3)
else
是-a
和-n
所谓的初选吗?
是否-a file
意味着“如果文件存在则为真。”?
-a
在“and”或“&&”表达式中将两个表达式链接在一起。此选项已弃用。
-n
检查字符串的长度是否非零。
您可以将测试表达式转换为以下伪代码:
if ( ($1 has nonzero length) and
($2 has nonzero length) and
($3 has nonzero length) )
该表达式中不检查文件是否存在,只检查参数是否已提供给脚本。
参数-a
和-n
可以在手册页中找到test
man test
运算符[ ... ]
通常用作系统的简写,test ...
并且可能在您的系统上具有相同的功能。
开关-a
并-n
严格来说不是bash
if
语句的一部分,因为该if
命令不处理这些开关。
我称它们为“开关”,但bash
您链接到的文档与“初级”指的是相同的东西(可能是因为这是讨论布尔表达式的一部分时使用的常用术语)。
In sh
scripts if
is a command that takes a command as its argument, executes it and tests its return code. If the return code is 0
the block of code following then
is executed up until the closing fi
or (if supplied) the following else
. If the return code was not 0
and an else
statement was supplied then the block of code following else
is executed up until the closing fi
.
You can see this effect by passing if
the command true
or the command false
, which are simple commands that do nothing and return 0
and non-0
respectively.
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
In the sample code you provided the command that you're passing to if
is [
, which is also sometimes known as test
. It is this command which takes the switches you're asking about. In bash
the test
command will be a built-in command; try type [
to learn its type. For built-in commands help
will show usage, so also run help [
to see documentation. Your system probably also has a /bin/[
and a /bin/test
and if you man test
you can see the manuals for those. Although the behavior of the built-in test
may not be identical to the behavior documented in the man pages, which is likely more verbose than the simple description you'll get from help [
, it will probably describe the behavior of the built-in [
command fairly accurately.
Knowing that the command you're running is test
we can consult help test
or man test
and read its usage. This will show that-n
tests the following argument and evaluates to true if it is not an empty string.
In the documentation of test
you will also see a the switch -e
. This switch tests the following argument and evaluates to true if that argument is a file or directory that exists. More useful still is the -f
switch which evaluates to true if the following argument exists and is a regular file (as opposed to a directory or a block device, or whatever).
The source of your confusion is probably that there can be two forms of -a
: Unary and binary. When -a
is used in a unary context, that is with one following argument but no preceding arguments, it treats its argument as a file and tests for its existence, just like the -e
switch. However, when -a
is used in a binary context, that is with one argument before it and one argument after it, it treats its arguments as other conditions and acts as a boolean AND operator.
In the interests of portability it is important to note that unary -a
is a non-standard extension which won't be found in POSIX. It is available in bash
and ksh
, however, so usage is probably widespread.
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