mik*_*erv 5 shell shell-script posix
在回答另一个非常好的问题时,我做出了以下断言:
根据我对 POSIX 规范的阅读,从解析的角度来看,使用一个或另一个没有区别。
POSIX 指定&&||
列表是复合命令,这意味着在执行组成的简单命令之前必须读入和解析整个列表。POSIX 还规定,如果一个命令跟在一个和另一个具有 0 退出状态的命令之后,则该命令不得扩展||OR
。当您考虑到&&||
保留字后面的命令很容易被另一个分组时,{ command || ( command ; list) ; }
就会使&&||
或 列出自己的复合命令的每个分支。
但是 POSIX 也以这种方式指定if...;then...;else...fi
构造的每个分支都是它自己的复合命令:
if compound-list
then
compound-list
[elif compound-list
then
compound-list] ...
[else
compound-list]
fi
Run Code Online (Sandbox Code Playgroud)
执行
if
复合列表;如果它的exit
状态为零,则then
复合列表将被执行并且命令将完成......
正是这个规范表明 athen...
或else...
保留字后面的字符串本身就是复合命令,而不仅仅是简单的命令,这意味着 shell 的解析器必须用命令和分隔符来表示它们才能正确操作。
所以基本上,then ' '
出于同样的原因不起作用:
function()
sh: line 2: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
...没有 - 它没有任何意义。
我知道...
[ -e doesntexist ] && $((i=1)) ; echo $i
Run Code Online (Sandbox Code Playgroud)
...将短路任何副作用,并由于\n
我在回答中指出的规范而仅导致ewline。的结果...
if [ -e doesntexist ]
then $((i=1))
fi
echo $i
Run Code Online (Sandbox Code Playgroud)
……一模一样。
但老实说if...fi
,我很少使用,以至于我不确定我是否误读了什么,所以当我收到一条评论表明我的解释不正确,如果我对此事有进一步的问题,我只需要问我就删除了答案来代替这个问题:我怎么弄错了——它们有什么不同?
&&
只有简单的情况才可以用和 来表示||
。该if
结构更为通用。if CONDITION; then FOO; fi
相当于CONDITION && FOO
(假设必要时正确使用大括号来分隔块),但是只要有一个else
(或elif
),一般情况下就不再可能了。
if CONDITION; then FOO; else BAR; fi\n
Run Code Online (Sandbox Code Playgroud)\n\n不等于
\n\nCONDITION && FOO || BAR\n
Run Code Online (Sandbox Code Playgroud)\n\n如果CONDITION
为 true,则两个构造都执行FOO
。如果FOO
为 false,则if
构造跳过BAR
,而&& \xe2\x80\xa6 ||
构造执行BAR
。
不,你不能用 来解决这个问题CONDITION && { FOO; true; } || BAR
。这使得复合命令在CONDITION
为 true 且FOO
为 false 时返回 true,而if CONDITION; then FOO; else BAR; fi
在这种情况下返回 false。
这是语义上的差异。此外,还有可读性:&&
and的嵌套使用||
的嵌套使用很快就变得难以破译。我不建议在同一个命令中使用两者,事实上 \xe2\x80\x94 特别是考虑到这两个运算符在 shell 中具有相同的优先级,而它们在 C 和大多数其他 C 语言(包括 Perl)中具有不同的优先级和红宝石)。