AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 447206
Accepted
masgo
masgo
Asked: 2018-06-01 13:24:10 +0800 CST2018-06-01 13:24:10 +0800 CST 2018-06-01 13:24:10 +0800 CST

如何防止一个命令触发ERR陷阱?

  • 772

我正在使用 ERR 陷阱来捕获我的 bash 脚本中的任何错误并输出发生的日志。(类似于这个问题:Trap, ERR, and echoing the error line)它按预期工作。唯一的问题是,在我的脚本中的某个时刻,exitcode !=0 预计会发生。在这种情况下如何使陷阱不触发?

这是一些代码:

err_report() {
    echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}

trap err_report ERR

然后在脚本的后面:

<some command which occasionally will return a non-zero exit code>

if [ $? -eq 0 ]; then
    <handle stuff>
fi

每次命令返回非零时,都会触发我的陷阱。我可以只为这部分代码避免这种情况吗?

我检查了这个问题:使用 `set -eu` 时 EXIT 和 ERR 陷阱的正确行为, 但我并没有真正了解如何将它应用于我的案例 - 如果完全适用的话。

bash trap
  • 3 3 个回答
  • 2634 Views

3 个回答

  • Voted
  1. Best Answer
    DopeGhoti
    2018-06-01T14:26:43+08:002018-06-01T14:26:43+08:00

    如果ERR trap立即“捕获”错误代码,则不会触发,这意味着您可以使用if语句和诸如此类的东西,而不必一直打开和关闭错误捕获。但是,您不能将检查$?用于流量控制,因为当您进行该检查时,您已经(可能)有未捕获的错误。

    如果您有一个预期会失败的命令——并且您不希望这些失败触发trap,您只需捕获失败。将它们包装在一个if语句中既笨重又冗长,但是这个速记很好用:

    /bin/false || :  # will not trigger an ERR trap
    

    但是,如果你想在命令失败时做一些事情,在if这里会很好:

    if ! /bin/false; then
        echo "this was not caught by the trap!"
    fi
    

    或者,else也将捕获错误状态:

    if /bin/false; then
        : # dead code
    else
        echo "this was not caught by the trap!"
    fi
    

    总而言之,set -e只有trap "command" ERR在存在没有立即和本质上考虑的错误情况时才会跳闸。

    • 5
  2. ilkkachu
    2018-06-01T13:31:32+08:002018-06-01T13:31:32+08:00

    ERR陷阱遵循与 相同的规则,set -e即它不会对用作条件的命令生效。所以,

    trap "echo error" ERR
    false                     # this should trigger the trap
    if ! false; then          # this shouldn't
         echo handle stuff
    fi
    

    请记住,if条件中的命令可以是任何命令,不一定是[ .. ]. 因此,如果您只想对命令的退出状态进行真/假评估,只需在if条件中直接使用它即可。

    如果您需要保存退出代码并避免ERR陷阱,您需要执行类似的操作

    somecmd && :; ret=$?
    

    在这里,&&将挤压ERR陷阱,但由于它仅在退出代码为零时运行,所以我们将知道退出代码在:.

    您可能想查看BashFAQ 105:为什么 set -e (或 set -o errexit,或陷阱 ERR) 没有达到我的预期?

    • 2
  3. JRFerguson
    2018-06-01T13:48:10+08:002018-06-01T13:48:10+08:00

    ERR您可以根据需要在部分代码期间启用/禁用陷阱。

    #!/bin/bash
    err_report() {
        echo "errexit on line $(caller)"
    }
    trap err_report ERR
    trap - ERR             # disable ERR trap
    false
    if [ $? -eq 0 ]; then
        printf "OK\n"
    else
        printf "FAIL\n"    # prints FAIL
    fi
    trap err_report ERR    # enable ERR trap
    false                  # prints errexit on line 14
    
    • 2

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve