bash if语句中的-n和-a选项有什么作用? [英] What do the -n and -a options do in a bash if statement?

查看:239
本文介绍了bash if语句中的-n和-a选项有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的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 testman test并阅读其用法.这将显示-n测试以下参数,如果它不是一个空字符串,则结果为true.

test的文档中,您还将看到一个开关-e.此开关测试以下参数,如果该参数是存在的文件或目录,则评估为true. -f开关仍然更有用,如果存在以下参数且该参数是常规文件(与目录或块设备等不同),则-f开关的计算结果为true.

您可能会感到困惑的根源可能是-a两种形式:一元和二进制.当在单一上下文中使用-a时,即具有一个后跟参数但没有没有前向参数时,它将其参数视为文件并测试其存在,只是就像-e开关一样.但是,在二进制上下文中使用-a时,即在前面有一个参数,在它后面有一个参数,它会将其参数视为其他条件,并充当布尔AND运算符.

为了便于携带,必须注意一元-a是非标准扩展,它不会在POSIX中找到.它在bashksh中可用,因此用法可能很广泛.

示例

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆