[英]In bash, either exit script without exiting the shell or export/set variables from within subshell
我有一个 function 运行一组脚本,这些脚本在当前 shell 中设置变量、函数和别名。
reloadVariablesFromScript() {
for script in "${scripts[@]}"; do
. "$script"
done
}
如果其中一个脚本有错误,我想退出脚本然后退出function,而不是杀死shell。
reloadVariablesFromScript() {
for script in "${scripts[@]}"; do
{(
set -e
. "$script"
)}
if [[ $? -ne 0 ]]; then
>&2 echo $script failed. Skipping remaining scripts.
return 1
fi
done
}
这会做我想要的,除了它不会在脚本中设置变量,无论脚本是成功还是失败。
如果没有子shell, set -e
会导致整个 shell 退出,这是不可取的。
有没有一种方法可以防止被调用的脚本继续出错而不杀死 shell 或从子外壳中设置/导出变量、别名和函数?
以下脚本模拟了我的问题:
test() {
{(
set -e
export foo=bar
false
echo Should not have gotten here!
export bar=baz
)}
local errorCode=$?
echo foo="'$foo'". It should equal 'bar'.
echo bar="'$bar'". It should not be set.
if [[ $errorCode -ne 0 ]]; then
echo Script failed correctly. Exiting function.
return 1
fi
echo Should not have gotten here!
}
test
如果最坏的情况变得更糟,因为这些脚本实际上并不编辑文件系统,我可以在子 shell 中运行每个脚本,检查退出代码,如果成功,则在子 shell 之外运行它。
请注意, set -e
有许多令人惊讶的行为——依赖它并不是普遍认为的好主意。 不过需要注意的是:我们可以将环境变量、别名和 shell 函数作为文本输出:
envTest() {
local errorCode newVars
newVars=$(
set -e
{
export foo=bar
false
echo Should not have gotten here!
export bar=baz
} >&2
# print generate code which, when eval'd, recreates our functions and variables
declare -p | egrep -v '^declare -[^[:space:]]*r'
declare -f
alias -p
); errorCode=$?
if (( errorCode == 0 )); then
eval "$newVars"
fi
printf 'foo=%q. It should equal %q\n' "$foo" "bar"
printf 'bar=%q. It should not be set.\n' "$bar"
if [[ $errorCode -ne 0 ]]; then
echo 'Script failed correctly. Exiting function.'
return 1
fi
echo 'Should not have gotten here!'
}
envTest
请注意,此代码仅在整个脚本段成功时评估任一export
; 问题文本和评论似乎表明如果不需要,这是可以接受的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.