Bash设置+ x而不打印

And*_*ler 78 bash shell

有没有人知道我们是否可以set +x在没有打印的情况下用bash 说:

set -x
command
set +x
Run Code Online (Sandbox Code Playgroud)

痕迹

+ command
+ set +x
Run Code Online (Sandbox Code Playgroud)

但它应该打印

+ command
Run Code Online (Sandbox Code Playgroud)

Bash是版本4.1.10(4).这对我来说已经有一段时间了 - 输出混乱了无用的set +x线路,使得跟踪设施没有那么有用.

小智 122

我有同样的问题,我能够找到一个不使用子shell的解决方案:

set -x
command
{ set +x; } 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,只是一个注释:命令后没有分号,这将无法正常工作; 并且使用分号但没有大括号的空格,将引发语法错误. (9认同)
  • 这会将退出状态归零. (9认同)
  • 另外,这里有一个更进一步的版本:`{ set +x; } 2>&-`。这会直接关闭 fd 2,而不是让它指向 /dev/null。有些程序在尝试打印到 stderr 时处理得不好,这就是为什么 /dev/null 通常是好的风格;但是 shell 的 `set -x` 跟踪处理得很好,所以它在这里工作得很好,而且它确实使这个咒语更短了一点。 (7认同)
  • 每次成功执行命令时,@ GarthKidd退出状态为零.`set + x`是一个如此成功的命令 (6认同)
  • 请解释一下这个咒语。 (3认同)
  • 确实是一个咒语。`{ }` 对命令进行分组,但 `set` 是一个[“内置”](https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html),而不是命令。看来`set +x 2>/dev/null`什么也没做(输出仍然打印)。因此,我们使用“{}”将其欺骗到命令中。这种认识是该解决方案的一个很好的副产品。 (3认同)
  • 如果您需要`command`的退出状态,可以使用以下变体:`{STATUS = $ ?; 设置+ x; } 2> / dev / null`。然后在闲暇时在随后的几行中检查`$ STATUS`。 (2认同)

cho*_*oba 41

您可以使用子shell.退出子shell后,设置x将丢失:

( set -x ; command )
Run Code Online (Sandbox Code Playgroud)

  • @chepner:你不能设置变量. (3认同)
  • ...而且你不能`cd`:它不会改变父shell中的当前目录. (2认同)

use*_*471 8

最近,当我对它感到恼火时,我就解决了这个问题:

shopt -s expand_aliases
_xtrace() {
    case $1 in
        on) set -x ;;
        off) set +x ;;
    esac
}
alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'
Run Code Online (Sandbox Code Playgroud)

这允许您启用和禁用xtrace,如下所示,其中我记录了如何将参数分配给变量:

xtrace on
ARG1=$1
ARG2=$2
xtrace off
Run Code Online (Sandbox Code Playgroud)

你得到的输出看起来像:

$ ./script.sh one two
+ ARG1=one
+ ARG2=two
Run Code Online (Sandbox Code Playgroud)


Oli*_*ver 7

基于@user108471的简化版本的解决方案怎么样:

shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ set +x; } 2>/dev/null'

trace_on
...stuff...
trace_off
Run Code Online (Sandbox Code Playgroud)