【问题标题】:Why is my ERR trap getting executed for TERM signal?为什么我的 ERR 陷阱会针对 TERM 信号执行?
【发布时间】:2018-10-09 14:47:34
【问题描述】:

在 bash 脚本中,我设置了两个陷阱:一个用于 TERM 信号,一个用于 ERR 信号。

当我向脚本发送 TERM 信号时,它会执行 ERR 陷阱,而不是 TERM 陷阱。

我在两台电脑上试过。其中之一是 Ubuntu 14.04.5 LTS,脚本运行良好。在另一个。 Scientific Linux 7.3 (Nitrogen),出现错误。

以下是脚本:

#!/bin/bash
trap "echo caught signal SIGTERM; exit 1;" SIGTERM
trap "echo caught signal SIGINT; exit 1;" SIGINT
trap "echo caught signal ERR; exit 1;" ERR

set -e
sleep 50

echo grep with err
grep sasas sasasa

当我在脚本 PID 上执行 kill -TERM -PID 时,我得到以下信息:

Terminated
caught signal ERR

如果sleep 命令结束,我会得到以下信息:

grep with err
grep: sasasa: No such file or directory
caught signal ERR

可能是什么问题?如何强制对 SIGTERM 信号执行 TERM 陷阱?

谢谢

【问题讨论】:

  • 您好,欢迎来到 Stack Overflow。我刚刚在 git-bash 中尝试过,以./script.sh & 的方式运行它按预期工作,我得到了caught signal SIGTERM。你如何运行脚本?
  • 谢谢。堆栈溢出已经为所有事情提供了大部分答案。这很棒。我完全按照你的方式执行它。在两个 Linux 机器上尝试过。我刚刚用 git-bash 进行了测试,它可以工作。会不会是我的系统管理员设置的某种全局设置?
  • 刚刚检查过。在测试的三个 bash 版本中,有效的是 2013 年的 4.3.11(1) 和 2016 年的 4.4.12(1)。不起作用的是 2011 年的 4.2.46(1)。知道这是否是问题所在?
  • 应该是因为你刚刚测试过:-)
  • 出于好奇,你能不能试试这个unix.stackexchange.com/a/314556 那个没用的?

标签: bash terminate


【解决方案1】:

不调用ERR 处理程序而不是 TERM 处理程序。它被称为之前。两个处理程序连续触发。您在示例代码中看不到这一点的原因是,因为您的 ERR 处理程序有一个 exit 1,所以程序在执行第二个处理程序之前退出。

如果您不想在错误处理程序中处理 TERM,可以按条件将其排除。在陷阱处理程序中,您可以通过$?获取信号代码:

#!/usr/bin/env bash
set -e

function error {
    if [ "$?" -eq 143 ]; then
        echo "Ignoring ERR, because this actually is TERM..."
        return
    fi
    echo "Handling ERR..."
}

function terminate {
    echo "Handling TERM..."
}

trap error ERR
trap terminate TERM

收到的代码是 143,因为 128 以上的代码意味着它来自一个信号:128 + 15 = 143

陷阱的定义顺序无关紧要,ERR 处理程序总是在 TERM 处理程序之前执行。

TLDP describes 退出代码 128+n 作为致命错误信号“n”。所以 n 类型的 error。考虑到这一点,我想在 TERM 处理程序之前调用 ERR 处理程序是有意义的。

由于您在评论中提到了 bash 版本,因此我没有看到取决于 Bash 版本的行为有任何差异。对我来说,bash 4.2.46 和 5.1.8 也是如此。

【讨论】:

  • 优秀的答案。也就是说,TLDP 因成为不良实践示例和过时建议的来源而臭名昭著——当官方手册不够用时,我建议使用 Bash Hackers' Wiki 和/或 Wooledge BashGuide。
猜你喜欢
  • 2020-02-07
  • 1970-01-01
  • 2016-12-18
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多