子 shell/子进程上的 bash 'nounset' 不会强制主脚本退出,如何在全局范围内解决这个问题?

子 shell/子进程上的 bash 'nounset' 不会强制主脚本退出,如何在全局范围内解决这个问题?

使用这个脚本:tstNounset.sh

#!/bin/bash
set -x 
set -o nounset;set -u

echo `echo $str`
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesn't reach here."

我想防止以全局方式达到“A”,而不需要检查每个变量。

也没有使用set -e(因为我已经处理了大多数错误和解决方法,因为许多也只是警告)。

我想是否可以有某种方法来检测“未绑定变量”甚至发生在子shell/子进程中,所以我可以强制退出吗?

我无法让事情顺利进行如何让 bash 脚本对 _each_ 命令的错误执行特定操作?或者如何使用 Trap 命令触发错误还。我找到了这个老问题也。

答案1

子壳

子 shell 无法杀死整个脚本。在 的影响下set -u,子 shell 无法告诉其父级“嘿,我希望你将此视为致命错误”。如果set -u它在子 shell 中有效但在其父 shell 中无效,那么这甚至没有意义。子 shell 所能做的就是返回一个非零退出代码。您可以手动或通过 来处理父级中的退出代码set -e

(set -u; …; echo $undefined_variable)
# here $? is nonzero
ret=$?; if [ $ret -ne 0 ]; then exit $ret; fi

子流程

您在这里所做的不是子 shell:您正在启动另一个程序。另一个程序恰好是 bash,它也是执行当前脚本的解释器,但这是一个巧合。 bash 调用的程序中的设置绝对没有理由导致 bash 本身退出。

set +e
bash -c 'do something'
echo "A - should and does reach here"

这与您所写的没有什么不同perl -e 'use strict; print $barf'— Perl 会死掉并返回非零状态,但这不会导致 bash 脚本退出(除了在 下set -e)。set -e如果您想在子进程返回非零返回代码时退出,请使用。

答案2

我的脚本编码错误,但可以修复:

看看第一条、第二条、第三条评论:

  • 第一个需要陷阱错误
  • 第二个错误,你要小心,不会被困住!不使用if ! ...将阻止使用 $? 获取返回值?
  • 第三,不要直接回显,使用中间变量,这样可以捕获错误

tstNounset.sh:

#!/bin/bash
trap 'ErrorHappened;exit 1' ERR #1st A TRAP ERR IS REQUIRED

set -x 
set -o nounset;set -u

#echo `echo $str`
nRet=0;if strA="`echo $str`";then : ;else nRet=$?;echo "Err$nRet";fi #2rd errors that you take care wont be trapped! do not use `if ! ...` will prevent getting return value with $?
echo "0 - should not reach here?"
strA="`echo $str`";echo "$strA" #3nd DO NOT ECHO DIRECTLY, use a intermediary variable so the error can be cautch
echo "1 - should not reach here?"
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesnt reach here."

相关内容