我在各种堆栈交换站点和 unix 帮助论坛上阅读了许多关于如何修改 shell 选项然后恢复它们的问题 - 我在这里找到的最全面的问题是如何“撤消”`set -x`?
在收到的智慧似乎是要么保存过的结果set +o或shopt -po再eval后来恢复到以前的设置。
但是,在我自己使用 bash 3.x 和 4.x 进行的测试中,errexit在执行命令替换时,该选项无法正确保存。
这是显示问题的示例脚本:
set -o errexit
set -o nounset
echo "LOCAL SETTINGS:"
set +o
OLDOPTS=$(set +o)
echo
echo "SAVED SETTINGS:"
echo "$OLDOPTS"
Run Code Online (Sandbox Code Playgroud)
和输出(我修剪了一些不相关的变量):
LOCAL SETTINGS:
set -o errexit
set -o nounset
SAVED SETTINGS:
set +o errexit
set -o nounset
Run Code Online (Sandbox Code Playgroud)
这似乎非常危险。errexit如果任何命令失败,我编写的大多数脚本都依赖于停止执行。我刚刚在我的一个脚本中找到了一个由此引起的错误,本应errexit在最后恢复的函数最终覆盖了它,在脚本运行期间将其设置回默认值off。
我希望能够做的是编写可以根据需要设置选项的函数,然后在退出之前正确恢复所有选项。但是好像在子shell中调用的命令替换,errexit是没有继承的。
我不知道如何在set +o不使用命令替换或跳过 FIFO 箍的情况下保存结果。我可以读取,$SHELLOPTS但它不是可写的或不可写的eval格式。
我知道一种替代方法是使用subshell 函数,但这会为能够记录输出以及传回多个变量带来很多麻烦。
可能相关:https : //stackoverflow.com/questions/29532904/bash-subshell-errexit-semantics(似乎有适用于 bash 4.4 及更高版本的解决方法,但我宁愿有一个便携式解决方案)
你在做什么应该有效。但是 bash 关闭了errexit命令替换中的选项,因此它保留了除此选项之外的所有选项。这是特定于 bash 和特定于errexit选项的。Basherrexit在 POSIX 模式下运行时会保留。从 bash 4.4 开始,bash 也不会errexit在命令替换中清除(如果shopt -s inherit_errexit有效)。
由于该选项在命令替换内部运行任何代码之前已关闭,因此您必须在外部检查它。
OLDOPTS=$(set +o)
case $- in
*e*) OLDOPTS="$OLDOPTS; set -e";;
*) OLDOPTS="$OLDOPTS; set +e";;
esac
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢这种复杂性,请改用 zsh。
setopt local_options
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2665 次 |
| 最近记录: |