首页 > 解决方案 > 为什么除非用大括号括起来,否则“set -x”(xtrace)输出不受重定向的影响?

问题描述

我正在使用“set -x”在 bash 脚本中启用命令回显。当我关闭回显时,我正在发出“set +x”,但我不希望该命令回显。为此,我发出命令:

{ set +x; } 2>/dev/null

这工作正常。但是,我并不完全理解为什么这有效,而以下内容则无效:

set +x 2>/dev/null 

显然命令的回显不会进入stderr,但我并不真正理解为什么花括号中带有分号的命令有效。

标签: bash

解决方案


您需要使用大括号的原因是xtrace日志记录(+ set +x您试图抑制的行)不是命令set +x本身输出的(该命令本身不会向 stderrstdout 写入任何内容)。相反,它是shell 调用 set +x的输出。

当您运行时set +x 2>/dev/null,这会将 stderr 重定向到/dev/null 仅用于执行set +x自身。它不会重定向 shell 在设置运行该命令时所做的事情,包括打印跟踪日志。

相比之下,当您运行时,它会在运行整个代码块之前{ set +x; } 2>/dev/null进行重定向,其中包括该块中每个命令的自然预命令设置。因此,该命令的设置也在重定向环境中运行。

您不希望它是其他情况——set -x如果someprogram 2>/dev/null根本不记录它已调用someprogram的内容有什么用?


顺便说一句,这非常类似于为什么 shell-builtintime命令的输出不会受到重定向,除非包装在更大的上下文中。有关更多信息,请参阅BashFAQ #32


推荐阅读