bash - 捕获子脚本中的 bash 错误

标签 bash bash-trap

我正在 bash 脚本(例如 parent.sh)中调用 bash 脚本(例如 child.sh),并且我希望脚本中包含错误(child.sh) 被困在我的父脚本 (parent.sh) 中。

我通读了 medium articlestack exchange post 。基于此,我认为我应该在父脚本上执行 set -E ,以便子 shell 继承 TRAPS。因此我的代码如下

parent.sh

#!/bin/bash
  
set -E

error() {
  echo -e "$0: \e[0;33mERROR: The Zero Touch Provisioning script failed while running the command $BASH_COMMAND at line $BASH_LINENO.\e[0m" >&2
  exit 1
}

trap error ERR
./child.sh

child.sh

#!/bin/bash
ls -al > /dev/null
cd non_exisiting_dir #To simulate error
echo "$0: I am still continuing after error"

输出

./child.sh: line 5: cd: non_exisiting_dir: No such file or directory
./child.sh: I am still continuing after error

您能否让我知道缺少什么,以便我可以继承父脚本中定义的 TRAP。

最佳答案

./child.sh不在“子shell”中运行。

子 shell 并不是 shell 的子进程,而 shell 恰好也是 shell,而是一个特殊的环境,其中来自 (...) 内部的命令, $(...)...|...运行,这通常是通过 fork 当前 shell 而不执行另一个 shell 来实现的。

如果你想运行child.sh在子 shell 中,然后从可以使用 (...) 创建的子 shell 中该脚本:

(. ./child.sh)

它将继承您的 ERR陷阱因为 set -E .

注释:

还有其他地方 bash 在子 shell 中运行命令:进程替换 ( <(...) )、协进程、 command_not_found_handle功能等

在某些 shell 中(但在 bash 中除外),管道中最左边的命令不在子 shell 中运行。例如ksh -c ':|a=2; echo $a'将打印 2。此外,并非所有 shell 都通过 fork 单独的进程来实现子 shell。

即使bash infamously允许通过环境(使用 export -f funcname )将函数导出到其他 bash 脚本,据我所知,这对于陷阱是不可能的;-)

关于bash - 捕获子脚本中的 bash 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64218270/

相关文章:

linux - ctrl+c 杀死带有子进程的 bash 脚本

html - XSLT:添加元素,从文件中读取内容

bash - bash 修剪中忽略大小写

bash - 为什么这个简单的 bash 陷阱会失败

TERM 的 bash 陷阱 - 我做错了什么?

Bash 信号捕获未检测到声明 'trap' block 后更改的变量

bash - 从使用读取和陷阱的 bash 脚本中清除退出

linux - 如何使用 %F bash shell 检测文件内容中的日期

regex - 为什么在使用正则表达式时 grep 会返回不同的结果?

json - jq 在空格后截断 ENV 变量