问题描述
我正在bash脚本(例如child.sh
)内调用bash脚本(例如parent.sh
),并且我希望脚本(child.sh
)中的错误被困父脚本(parent.sh
)。
我通读了medium article和stack exchange post。基于此,我认为我应该在父脚本上执行set -E
,以便TRAPS被子shell继承。因此我的代码如下
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中运行child.sh
,那么请从{shell}中使用您可以使用(...)
创建的子shell中的脚本来
(. ./child.sh)
由于ERR
,它将继承您的set -E
陷阱。
注意:
bash在其他地方在子外壳中运行命令:进程替换(<(...)
),协同进程,command_not_found_handle
函数等。
在某些shell中(但不是在bash中),管道中最左边的命令不在子shell中运行。例如ksh -c ':|a=2; echo $a'
将打印2。而且,并非所有的Shell都通过分叉一个单独的进程来实现子Shell。
即使bash infamously允许通过环境(使用export -f funcname
)将功能导出到其他bash脚本,对于陷阱;-)来说,这也是AFAIK