首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Shell选项更改(例如,设置-o xtrace)不会从括号内应用

Shell选项更改(例如,设置-o xtrace)不会从括号内应用
EN

Stack Overflow用户
提问于 2018-02-02 08:46:39
回答 2查看 813关注 0票数 0

我正在尝试为我的bashrc创建一个别名,如果没有设置xtrace,它将启用选项nounsetxtrace,如果设置了它们,它将禁用它们,从而允许我切换“调试模式”。

我有这个:

代码语言:javascript
复制
alias debug="[[ \$(set -o | grep xtrace) = *off ]] && (set -o nounset; set -o xtrace; echo 'Debug mode ON') || (set +o nounset; set +o xtrace; echo 'Debug mode OFF')"

我的问题是,从终端输出来看,这似乎是可行的,但是当我运行set -o时,nounsetxtrace选项都没有改变。原因是这两个选项都在括号()中,因此这些选项不会应用于当前终端。

例如,这也不起作用(xtrace保持关闭):

代码语言:javascript
复制
(set -o xtrace)

我该如何解决这个问题?有没有一种方法可以不带括号地写上面的别名,或者从括号内应用选项?为什么会发生这种情况?

EN

Stack Overflow用户

回答已采纳

发布于 2018-02-02 09:04:50

$(…)(set -o ...;)中的圆括号创建子shell。子shell中所做的更改不会对父shell产生任何影响,无论是环境变量还是shell选项。

您似乎想要嘈杂地切换跟踪标志。这也称为-x标志,在$-中可见,该参数包含当前设置的单字母标志。您还可以将set -uset +u用于set -o nounset选项。

因此,您可以在以下内容上使用一些变体:

代码语言:javascript
复制
alias debug='case "$-" in
             (*x*) set +xu; echo "Debug mode OFF";;
             (*)   set -xu; echo "Debug mode ON";;
             esac'

如前所述,如果您愿意,可以将其展平到单行上。还有其他方法可以编写,使用if和适当的条件。我仍然喜欢case,但是在使用[[命令进行Bash之前,我已经学会了shell脚本编程。

您还可以使用{}来代替子shell表示法。因此,对您的脚本的最低限度的更改将是:

代码语言:javascript
复制
alias debug="[[ \$(set -o | grep xtrace) = *off ]] && { set -o nounset; set -o xtrace; echo 'Debug mode ON'; } || { set +o nounset; set +o xtrace; echo 'Debug mode OFF'; }"

请注意,在}之前必须有一个'end of command‘-实际上,这意味着换行符或分号。并且{}必须与周围的符号分开。我不喜欢使用$(set -o | grep xtrace);与使用$-相比,它非常笨重。你可以通过再次使用$-来解决这个问题:

代码语言:javascript
复制
alias debug='[[ ! $- =~ x ]] && { set -o nounset -o xtrace; echo "Debug mode ON"; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'

当您打开debug时,这有点嘈杂;最好写成:

代码语言:javascript
复制
alias debug='[[ ! $- =~ x ]] && { echo "Debug mode ON"; set -o nounset -o xtrace; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'

在关闭跟踪的情况下完成echo。当调试当前处于打开状态并准备将其关闭时,您仍然可以看到测试;这是不可避免的。

您还可以使用显式if/then/else/fi

代码语言:javascript
复制
alias debug='if [[ $- =~ x ]]; then set +o nounset +o xtrace; echo "Debug mode OFF"; else echo "Debug mode ON"; set -o nounset -o xtrace; fi'

或者将其压缩为:

代码语言:javascript
复制
alias debug='if [[ $- =~ x ]]; then set +xu; echo "Debug mode OFF"; else echo "Debug mode ON"; set -xu; fi'
票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48574100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档