从左到右?或相反亦然?
例子:
If [! -z "$ foo"] && [$ foo2 -eq 0]; then
echo "something"
fi
首先进行什么评估?
[! -z "$ foo"]
或者
[$ foo2 -eq 0]
谢谢!
答案1
在 shell 脚本中说
if [ ! -z "$foo" ] && [ "$foo2" -eq 0 ]; then
echo 'something'
fi
第一个测试[ ! -z "$foo" ]
(最好写成[ -n "$foo" ]
)将首先运行。第二次测试将仅有的如果第一个测试成功则运行。如果两个都测试成功,意思$foo
是一个值不为空并且$foo2
算术值等于0,那么echo
将被执行。
该&&
运算符的工作方式与其他语言中的类似运算符类似。外壳实现短路评估&&
如果左侧是,则只会评估右侧真的。
这个特定的if
语句也可以在不使用关键字的情况下编写if
,如
[ ! -z "$foo" ] && [ "$foo2" -eq 0 ] && echo 'something'
尽管使用if ...; then ...; fi
恕我直言更清楚。
同样,echo
只有在以下情况下才会执行两个都前面的测试成功了。
答案2
太长了;博士
如中所述你已有的答案,根据定义与列表在 shell 命令语言中,[ ! -z "$foo" ]
首先执行,然后仅当它返回退出状态为零时才[ "$foo2" -eq 0 ]
执行。
Bash 中命令的执行顺序在“Shell 命令”部分中指定Bash 参考手册。在下文中,我假设此处提供的定义可能会逐字复制(即使为了方便起见,未将其格式化为引用)。
对于 Bash 和其他 POSIX 兼容的 shell,更正式(但可能不太友好)的定义可以在“Shell 命令语言”一章(特别是“Shell 命令”和“Shell 语法”段落)中找到。The Open Group 基本规格。
在代码中
if [ ! -z "$foo" ] && [ "$foo2" -eq 0 ]; then
echo "something"
fi
我们有一个if
复合命令, 一个并列表和三个简单的命令。
条件构造的一般语法if
是
if test-commands; then
consequent-commands;
[elif more-test-commands; then
more-consequents;]
[else alternate-consequents;]
fi
如果 的退出状态test-commands
为零,则consequent-commands
执行该子句。
我们的test-commands
子句是一个 AND 列表,它是一个序列管道用 分隔&&
,如
command1 && command2
当且仅当 的退出状态为零command2
时才执行where 。command1
AND 列表以左关联性执行。因此:
command1 && command2 && command3
执行起来就好像它被写成一样(使用括号作为伪代码分组运算符并暂时忘记它们在 Bash 语言中的含义):
(((command1) && command2) && command3)
在我们的 AND 列表中
[ ! -z "$foo" ] && [ "$foo2" -eq 0 ]
第一条管道
[ ! -z "$foo" ]
首先执行。仅当第二条管道成功时
[ "$foo2" -eq 0 ]
被执行。列表中最后执行的命令的退出状态是 所考虑的状态if
。
管道是由一个控制运算符|
或分隔的一个或多个命令的序列|&
。我们的两个管道都只是简单的命令。
简单命令是由 分隔的单词序列blanks
,由 shell 的一个控制运算符终止。简单的命令不会造成执行顺序问题。
根据记录,AND 列表中的简单命令由(内置)命令[
及其四个参数组成,分别为!
, -z
, "$foo"
,]
和"$foo2"
, -eq
, 0
, ]
。
最后,consequent-commands
我们的复合命令的子句if
是简单命令echo "something"
——同样,它不会造成任何执行顺序问题。