我想在我的脚本中临时设置-x,然后恢复到原始状态。
有没有办法在不启动新子外壳的情况下做到这一点?就像是
echo_was_on=.......
... ...
if $echo_was_on; then set -x; else set +x; fi
您可以检查 的值$-
以查看当前选项;如果它包含一个 x,则它已被设置。你可以像这样检查:
old_setting=${-//[^x]/}
...
if [[ -n "$old_setting" ]]; then set -x; else set +x; fi
万一你不熟悉:${}
上面是一个Bash Substring Replacement,它接受变量-
并替换任何不是 ax
的东西,只留下x
后面(或者什么都没有,如果没有 x)
reset_x=false
if ! [ -o xtrace ]; then
set -x
reset_x=true
fi
# do stuff
"$reset_x" && set +x
您使用 test 测试 shell 选项-o
(使用[
如上或 with test -o
)。如果xtrace
未设置该选项 ( set +x
),则设置它并设置一个标志以稍后将其关闭。
在函数中,您甚至可以设置RETURN
陷阱以在函数返回时重置设置:
foo () {
if ! [ -o xtrace ]; then
set -x
trap 'set +x' RETURN
fi
# rest of function body here
}
或在案例陈述中
case $- in
*x* ) echo "X is set, do something here" ;;
* ) echo "x NOT set" ;;
esac
以下是基于@shellter和@glenn jackman 的答案的可重用函数:
is_shell_attribute_set() { # attribute, like "e"
case "$-" in
*"$1"*) return 0 ;;
*) return 1 ;;
esac
}
is_shell_option_set() { # option, like "pipefail"
case "$(set -o | grep "$1")" in
*on) return 0 ;;
*) return 1 ;;
esac
}
使用示例:
set -e
if is_shell_attribute_set e; then echo "yes"; else echo "no"; fi # yes
set +e
if is_shell_attribute_set e; then echo "yes"; else echo "no"; fi # no
set -o pipefail
if is_shell_option_set pipefail; then echo "yes"; else echo "no"; fi # yes
set +o pipefail
if is_shell_option_set pipefail; then echo "yes"; else echo "no"; fi # no
更新:对于 Bash,test -o
是完成相同任务的更好方法,请参阅@Kusalananda 的回答。
还:
case $(set -o | grep xtrace | cut -f2) in
off) do something ;;
on) do another thing ;;
esac
不那么冗长
[ ${-/x} != ${-} ] && tracing=1 || tracing=0
如果您对 bash 扩展(非 POSIX)没问题并且您的 bash 版本支持它,这应该可以准确回答问题。
[[ $- =~ x ]] && echo_was_on=true || echo_was_on=false