2010-07-06 68 views
3

在bash脚本中评估test[表达式的顺序是什么?这与它们的写入顺序是否相同?他们都被评估过吗?什么是bash“测试”命令评估命令?

在下面的例子:

if [ expr1 -a -n expr2 ] 

expr2的被如果expr1的是假的评估?

+0

该示例不会在bash中解析。 - 检查文件是否存在,-n检查字符串的非零性。该示例导致“参数太多”错误。 – BjoernD 2010-07-06 07:53:06

+0

我还没有在'bash'或'test'的manpages中找到关于评估顺序的任何内容,所以它似乎与实现有关。由于'test'表达式不会改变状态或引发异常,因此评估顺序和懒惰无关紧要。 – Philipp 2010-07-06 07:55:04

+1

@Bjoern,它解析得很好。我不确定你正在运行什么bash,但它在CygWin下工作正常。这是一种老式的测试方法,使用'-a'来做“和”。 – paxdiablo 2010-07-06 08:01:54

回答

11

自从我使用特定的语法已经很长时间了。如今,我更喜欢:

if [[ expr1 && -n expr2 ]] 

,因为我知道这些是短路。该bash手册页明确指出:

如果表达式的值是足以决定整个条件表达式的返回值&&||运营商不计算表达式2。

它似乎没有清楚说明的一种方式或另一种为[test变体(使用-a)。

但是,为了进一步提高您的知识和我的知识(并指出为什么开源是一件好事),我开始使用bash源代码。

事实证明,这是而不是在这种情况下短路。代码的特定件(压缩位的可读性):

static int or() { 
    int value, v2; 
    value = and(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'o' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = or(); 
     return (value || v2); 
    } 
    return (value); 
} 

static int and() { 
    int value, v2; 
    value = term(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'a' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = and(); 
     return (value && v2); 
    } 
    return (value); 
} 

您可以在这两个案例看,它继续解释表达式无论第一个表达式的状态。

这是从bash 2.5,但我刚刚检查了4.1源,以及它没有改变。来源从horse's mouth直接拉。

所以。底线:似乎在使用-a-otest[时评估所有子表达式。

+1

Holy ...... bash!你很好 :) – Tom 2010-07-06 08:45:05