【问题标题】:Check current bash verbosity检查当前的 bash 详细程度
【发布时间】:2018-06-03 10:51:52
【问题描述】:

我知道 bash 可以使用set -v 设置为详细模式,但是我想编写一个即使从详细脚本调用也不会以详细模式运行的函数。

虽然我知道我可以通过在函数开头使用 set +v 并以 set -v 结束它来禁用冗长,但这意味着我的函数会将任何调用它的脚本设置为详细,即使它不是在调用它之前不要冗长。

理想情况下,我会在函数开始时检查详细程度,禁用详细程度,并在函数结束时恢复详细程度更改。

有没有办法找到当前的详细程度?

【问题讨论】:

  • 在我看来,只有开和关。

标签: bash verbosity


【解决方案1】:
if [[ $- =~ v ]]; then 
  echo "verbose enabled"
else
  echo "verbose disabled"
fi

$-:包含当前启用的选项集。见:help set

【讨论】:

    【解决方案2】:
    if test -o verbose; then
       echo 'shell is running in verbose mode'
    else
       echo 'shell is not running in verbose mode'
    fi
    

    或者,等价的,

    if [[ -o verbose ]]; then
       echo 'shell is running in verbose mode'
    else
       echo 'shell is not running in verbose mode'
    fi
    

    bash 中内置的test 实用程序能够使用-o OPTION 测试是否设置了shell 选项。在交互式bash shell 中查看help test,或阅读bash 手册。

    你的函数可能看起来像

    foo () {
        if [[ -o verbose ]]; then
            set +v
            trap 'set -v' RETURN
        fi
    
        # do stuff
    }
    

    这会在调用函数时检测-v 是否处于活动状态。如果是,则将其关闭并安装一个 RETURN 陷阱,当函数返回时(在函数结束时,或通过显式的 return 语句)将其重新打开。

    【讨论】:

      【解决方案3】:

      检查详细模式选项与检查任何其他 bash 选项相同,请参阅In bash, how to get the current status of set -x?

      试试这个:

      func() {
         local old_verbosity_level=${-//[^v]}
         set +v
         ...
         if [ -n "$old_verbosity_level" ]; then set -v; else set +v; fi
      }
      

      或更棘手的:

      func() {
         local old_verbosity_level=${-//[^v]}
         set +v
         ...
         ${old_verbosity_level:+set -v}
      }
      

      【讨论】:

        【解决方案4】:

        根据您的功能及其用途,您可以使用(..) 子shell 限制选项更改的范围:

        foo() (
          set +vx
          echo "not verbose"
        )
        
        set -v
        foo
        echo "still verbose"
        

        【讨论】: