bash - 为什么 bash 在 ERR 陷阱中退出 0 时抑制标准输出?

标签 bash

我尝试在 bash 中设置 ERR 陷阱并注意到一些奇怪的行为。如果退出代码为 0,当我运行此脚本时,Bash 似乎不会将我的 echo 命令输出到控制台,但是,如果退出代码为非零,则输出文本。这是bash中的错误吗?或者对此有什么解释吗?

./testing.sh:

#!/bin/bash

set -eE

handleerror() {
  echo "TEST"
  exit 0
}
trap "handleerror" ERR

OUTPUT=$(mkdir test/test 2>&1)

如果我运行上面的脚本,它什么都不输出。如果我将 exit 0 行更改为 exit 1,我将看到以下内容:

> ./testing.sh
TEST

供引用:

> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.

最佳答案

简短回答:输出没有被抑制;它被命令替换捕获。更改 handleerror 的退出状态会更改它被调用的次数:一次在命令替换内部,一次在外部。运行 bash -x testing.sh 以查看差异。


您必须考虑 handlerror 实际何时被调用。 mkdir 的失败触发调用,并且由于 handleerror 在命令替换中被调用,它的输出被捕获并分配给 OUTPUT。如果将 echo "$OUTPUT" 添加到脚本末尾,您将看到

mkdir: test: No such file or directory
TEST

作为脚本的输出。此行执行是因为 handleerror 的 0 退出状态阻止 set -e 提前退出脚本。

现在,将 exit 0 更改为 exit 1。序列开始相同:mkdir 失败,handleerror 被调用,其输出由命令替换捕获。但是,现在 handleerror 本身的退出状态为 1,这使得命令替换和赋值语句的退出状态也为 1。这会做两件事:它会导致 set -eecho "$OUTPUT" 运行之前中止脚本,它会导致 handleerror 运行一个第二次。现在当你运行脚本时,你所看到的就是

TEST

由第二次调用 handleerror 产生。

关于bash - 为什么 bash 在 ERR 陷阱中退出 0 时抑制标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56238922/

相关文章:

linux - 用于迭代目录并创建 tar 文件的 bash 脚本

linux - 解析 shell 脚本中的配置文件

linux - bash - 获取子进程的 io 统计信息

linux - 连续的 bash 脚本 - 进程终止时显示自定义错误

bash - 在 bash 中生成随机字符

linux - 如何在 shell 脚本中从第 3 行等中减去第 1 行和第 2 行中的数据?

Bash:用管道杀死

bash - 为什么 shell 会忽略通过变量传递给它的参数中的引号字符?

bash - 用****屏蔽输出卡号

linux - 修改 shell 脚本以返回与正确用户 ID 关联的名称