Bash Shell选项更改(例如set-o xtrace)不会从括号内应用
我正在尝试为我的bashrc创建一个别名,如果未设置Bash Shell选项更改(例如set-o xtrace)不会从括号内应用,bash,shell,sh,Bash,Shell,Sh,我正在尝试为我的bashrc创建一个别名,如果未设置xtrace,它将启用选项nounset和xtrace,如果已设置,它将禁用这些选项,允许我切换“调试模式” 我有这个: 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
xtrace
,它将启用选项nounset
和xtrace
,如果已设置,它将禁用这些选项,允许我切换“调试模式”
我有这个:
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
时,nounset
和xtrace
两个选项都没有更改。原因是这两个选项都在括号内()
,因此这些选项不会应用于当前终端
例如,这也不起作用(xtrace
处于禁用状态):
我如何解决这个问题?有没有办法在不使用括号的情况下编写上面的别名,或者从括号内应用选项?为什么会发生这种情况?在
$(…)
或(set-o…;)
中创建一个子shell。在子shell中所做的更改对父shell没有影响,无论是环境变量还是shell选项
您似乎想要响亮地切换跟踪标志。这也称为-x
标志,在$-
中可见,该参数包含当前设置的单字母标志。您还可以使用set-u
和set+u
作为set-o-set
选项
因此,您可以在以下方面使用一些变体:
alias debug='case "$-" in
(*x*) set +xu; echo "Debug mode OFF";;
(*) set -xu; echo "Debug mode ON";;
esac'
如前所述,如果您愿意,可以将其展平到一行上。还有其他编写方法,使用if
和适当的条件。我仍然喜欢case
,但在使用[
命令进行Bash之前,我就学会了shell脚本
您还可以使用{
和}
而不是子shell符号。因此,对脚本的一组最低限度的更改是:
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 | grep xtrace)
;与使用$-
相比,这是非常沉重的。您可以再次使用$-
来解决这一问题:
alias debug='[[ ! $- =~ x ]] && { set -o nounset -o xtrace; echo "Debug mode ON"; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'
当您打开debug时,这有点嘈杂;最好写为:
alias debug='[[ ! $- =~ x ]] && { echo "Debug mode ON"; set -o nounset -o xtrace; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'
echo
是在跟踪关闭时完成的。当调试当前处于打开状态且即将关闭时,您仍然可以看到测试;这是不可避免的
如果/则
/否则
/则
/可以使用显式的fi
:
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'
或者将其压缩为:
alias debug='if [[ $- =~ x ]]; then set +xu; echo "Debug mode OFF"; else echo "Debug mode ON"; set -xu; fi'
$(…)
或(set-o…;)
中的括号创建子shell。在子shell中所做的更改对父shell没有影响,无论是环境变量还是shell选项
您似乎想大声切换跟踪标志。这也被称为-x
标志,在$-
中可见,该参数包含当前设置的单字母标志。您还可以使用set-u
和set+u
作为set-o nounoset
选项
因此,您可以在以下方面使用一些变体:
alias debug='case "$-" in
(*x*) set +xu; echo "Debug mode OFF";;
(*) set -xu; echo "Debug mode ON";;
esac'
正如所写的,如果您愿意,可以将其平铺到一行上。还有其他方法可以编写它,使用if
和适当的条件。我仍然喜欢case
,但在使用[
命令进行Bash之前,我就学习了shell脚本
您还可以使用{
和}
而不是子shell符号。因此,对脚本的一组最低限度的更改是:
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 | grep xtrace)
;与使用$-
相比,这是非常沉重的。您可以再次使用$-
来解决这一问题:
alias debug='[[ ! $- =~ x ]] && { set -o nounset -o xtrace; echo "Debug mode ON"; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'
当您打开debug时,这有点嘈杂;最好写为:
alias debug='[[ ! $- =~ x ]] && { echo "Debug mode ON"; set -o nounset -o xtrace; } || { set +o nounset +o xtrace; echo "Debug mode OFF"; }'
echo
是在跟踪关闭时完成的。当调试当前处于打开状态且即将关闭时,您仍然可以看到测试;这是不可避免的
如果
/则
/否则
/则
/可以使用显式的fi
:
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'
或者将其压缩为:
alias debug='if [[ $- =~ x ]]; then set +xu; echo "Debug mode OFF"; else echo "Debug mode ON"; set -xu; fi'
{}
可以将多个命令组合在一起,而无需像()
那样创建子shell。语法有点不同;您需要确保在{}
和任何单词之间保留空格,否则它可以解释为{a,b}→ a b
大括号展开,命令需要以a
;(或&
)终止
{}
可以将多个命令组合在一起,而无需像()
那样创建子shell。语法有点不同;您需要确保在{}
和任何单词之间保留空格,否则它可以解释为{a,b}→ b
大括号展开,命令需要以;
(或&
)终止。括号(在$(…)
和(set-o…;)
中)创建子shell。在子shell中所做的更改对父shell没有影响,无论是环境变量还是shell选项。这是需要的、有文档记录的、预期的行为,而不是需要“固定”的行为。括号(在$(…)
和(set-o…;)
中)创建一个子shell。在子shell中所做的更改对父shell没有影响,无论是环境变量还是shell选项。这是需要的、有文档记录的、预期的行为,而不是需要“修复”的内容。