【问题标题】:Redirecting errors *from redirection operations themselves*重定向错误*来自重定向操作本身*
【发布时间】:2020-10-22 10:29:55
【问题描述】:

假设我在当前目录中有一个名为 a.txt 的文件。它的 chmod 值为 000。

因此,如果我尝试写入它,我会得到以下输出:

> printf "Hello" >> a.txt
-bash: a.txt: Permission denied

我怎样才能抑制这个输出?我已经尝试将2>/dev/null 附加到我的命令中,但这种重定向似乎并没有像我最初希望的那样工作。

【问题讨论】:

  • 顺便说一句,您是否希望您的程序仍然运行,而不是静默地不被调用?对于printf,显然,如果它不能写入标准输出,那么运行它是没有意义的;但我可以想到一些情况,其中可能存在您真正想要的其他副作用。
  • @CharlesDuffy 出于我的目的,这将在一个隐藏大部分输出并使用打印语句来解释正在发生的事情的一般概念的 bash 脚本中。此 printf 是 if 语句的一部分,如果写入失败,则会告知用户写入失败并在退出之前与我联系,代码为 1。
  • 明白了。顺便说一句,信息和诊断信息通常应该打印到 stderr 而不是 stdout。这不仅仅是关注POSIX conventions 的问题,还可以确保如果您的标准输出通过管道传输到其他地方,您的日志仍然显示在正确的位置,并确保这些日志立即打印而不是缓冲(因为标准输出默认缓冲当打印到非 TTY 目的地时——为什么在这种情况下内容没有立即显示是这里的常见问题解答)。

标签: bash file stdout io-redirection stderr


【解决方案1】:

重定向是按顺序评估的,因此要抑制消息,您必须在尝试重定向 stdout 之前重定向 stderr:

printf "Hello" 2> /dev/null >> a.txt

【讨论】:

    【解决方案2】:

    The answer by that other guy 是正确的,如果您还想抑制错误正在运行的命令,而不仅仅是在启动之前执行的重定向。

    如果您想抑制来自重定向本身的消息,而不是抑制来自实际执行的错误消息,那么您需要一对额外的重定向,以临时存储 stderr 的原始值,以便您以后可以恢复它:

    printf "Hello" 3>&2 2>/dev/null >>a.txt 2>&3 3>&-
    

    分解如下:

    • 3>&2 将原始 stderr (FD 2) 复制到默认情况下未使用的文件描述符 (FD 3),从而创建原始目标的备份。
    • 2>/dev/null 然后将 stderr 指向 /dev/null
    • >>a.txt 将 stdout (FD 1) 指向 aa.txt,stderr 指向 /dev/null
    • 2>&3 将我们在 FD 3 上的备份复制回 FD 2,将 stderr 恢复到其原始目标,以便正在运行的程序可以记录错误。
    • 3>&- 删除备份,保留文件描述符表,如果我们什么都不做的话。 (通常可以安全地忽略这一点——大多数表现良好的程序会简单地忽略非标准文件描述符的初始值,除非明确告知要这样做)。

    【讨论】:

    • 优秀的答案。值得注意的是,如果您以交互方式运行,您可能希望简化为:cmd 2> /dev/null > output 2> /dev/tty
    • 聪明。 @thatotherguy 的评论是我所需要的全部内容,但我肯定会记下这一点以供将来参考!
    • 谢谢!顺便说一句,这是一个很好的第一个问题!独立,同时保持简洁;格式正确,不是我们一遍又一遍看到的常见问题解答,描述了您尝试过的内容等。
    猜你喜欢
    • 2013-07-10
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    相关资源
    最近更新 更多