我正在 bash 脚本(例如 parent.sh
)中调用 bash 脚本(例如 child.sh
),并且我希望脚本中包含错误(child.sh
) 被困在我的父脚本 (parent.sh
) 中。
我通读了 medium article和 stack 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/