bash - 为什么除非用大括号括起来,否则“set -x”(xtrace)输出不受重定向的影响?
问题描述
我正在使用“set -x”在 bash 脚本中启用命令回显。当我关闭回显时,我正在发出“set +x”,但我不希望该命令回显。为此,我发出命令:
{ set +x; } 2>/dev/null
这工作正常。但是,我并不完全理解为什么这有效,而以下内容则无效:
set +x 2>/dev/null
显然命令的回显不会进入stderr,但我并不真正理解为什么花括号中带有分号的命令有效。
解决方案
您需要使用大括号的原因是xtrace
日志记录(+ set +x
您试图抑制的行)不是从命令set +x
本身输出的(该命令本身不会向 stderr或stdout 写入任何内容)。相反,它是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。
推荐阅读
- javascript - 如何在我的代码 later.on 中使用在事件内部生成的变量(Leflet 层数组)
- flutter - 将异步值返回给 initState()
- java - 无法删除文件,因为它已被另一个进程使用,即使 Stream 已关闭
- c# - ASP.NET Core API 接收 JsonArray 并将对象发布到 DB(实体框架)
- tron - 无法从 Trongrid 获得 TRON 合约 ABI
- android - 使用 CountryCode 选择器自定义 TextInputEditText
- wordpress - 在函数文件中更改自定义帖子类型 slug
- javascript - 如何在javascript中检查两个字段是否匹配?
- azure-devops - Azure DevOps 变量和多行值
- html - bootstrap4 手风琴不能通过传递索引在 ngFor 中工作