bash if语句中的-n和-a选项有什么作用? [英] What do the -n and -a options do in a bash if statement?
问题描述
在下面的bash if
语句中,-a
和-n
选项执行什么功能?
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
REFNAME=$(basename $3)
else
是-a
和-n
,即所谓的 主要 ?
-a file
的意思是如果文件存在则为真".
挑剔
开关-a
和-n
严格不是bash
if
语句的一部分,因为if
命令不会处理这些开关.
什么是初选?
我称它们为开关",但是链接到的bash
文档与"primaries"具有相同的含义(可能是因为这是讨论布尔表达式的各个部分时常用的术语).
背景和文档
在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
测试以下参数,如果它不是一个空字符串,则结果为true.
在test
的文档中,您还将看到一个开关-e
.此开关测试以下参数,如果该参数是存在的文件或目录,则评估为true. -f
开关仍然更有用,如果存在以下参数且该参数是常规文件(与目录或块设备等不同),则-f
开关的计算结果为true.
您可能会感到困惑的根源可能是-a
的两种形式:一元和二进制.当在单一上下文中使用-a
时,即具有一个后跟参数但没有没有前向参数时,它将其参数视为文件并测试其存在,只是就像-e
开关一样.但是,在二进制上下文中使用-a
时,即在前面有一个参数,在它后面有一个参数,它会将其参数视为其他条件,并充当布尔AND运算符.>
为了便于携带,必须注意一元-a
是非标准扩展,它不会在POSIX中找到.它在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
What function do the -a
and -n
options perform in the following bash if
statement?
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
REFNAME=$(basename $3)
else
Are -a
and -n
so called primaries?
Does -a file
mean "True if file exists."?
Nitpicking
The switches -a
and -n
are not strictly part of a bash
if
statement in that the if
command does not process these switches.
What are primaries?
I call them "switches", but the bash
documentation that you linked to refers to the same thing as "primaries" (probably because this is a common term used when discussing parts of a boolean expression).
Background and docs
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.
The behavior of -a and -n
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.
Example
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
这篇关于bash if语句中的-n和-a选项有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!