当与 || 一起使用时,为什么此复合命令 {...} 不会因错误而退出?

Min*_*nix 4 bash shell-script set

我正在尝试运行此脚本:

#!/bin/bash -e

{ 
    echo "Doing something"; 
    will_fail                 # like `false` 

    echo "Worked"; 
} || echo "Failed"
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,will_fail失败了,但我在命令行上没有看到“失败”,而是“工作”。

为什么复合命令will_fail失败后没有错误退出?

Kus*_*nda 12

Failed不会被打印,因为复合命令的退出状态是在 中执行的最后一个命令的状态{ ...; },即echo. 的echo成功,所以化合物命令退出时的零退出状态。

以下将输出三个字符串:

{ echo "Do something"; echo "Worked"; false; } || echo "Failed"
Run Code Online (Sandbox Code Playgroud)

POSIX 标准

除非另有说明,命令的退出状态应为该命令执行的最后一个简单命令的退出状态。


这里发生了几件事(总结):

  • 你用set -eactive跑。如果任何命令返回非零退出状态(广义而言),这将导致 shell 退出。但是,这在这里并不适用,因为will_fail命令是(复合命令,是||列表的一部分)的一部分(而不是最后一个)。

    同样,来自POSIX 标准(我的重点):

    -e设置应执行以下化合物列表时被忽略whileuntilif,或elif保留字,管道期初!保留字,或任何命令比上次以外的AND,OR名单。

  • ||列表中的最后一个简单命令是echo "Failed". 这决定了复合命令的整体退出状态。由于它执行成功(并且will_fail不会导致shell退出),状态将为零,这意味着||不会执行的另一侧。