Bash 重定向操作本身导致的重定向错误**

Bash 重定向操作本身导致的重定向错误**,bash,file,stdout,io-redirection,stderr,Bash,File,Stdout,Io Redirection,Stderr,假设我在当前目录中有一个名为a.txt的文件。它的chmod值是000 因此,如果我尝试写入它,我会得到以下输出: > printf "Hello" >> a.txt -bash: a.txt: Permission denied 如何抑制此输出?我已尝试将2>/dev/null附加到我的命令,但此重定向似乎没有像我最初希望的那样工作。重定向是按顺序计算的,因此要抑制消息,您必须在尝试重定向stdout之前重定向stderr: printf "H

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

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

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

如何抑制此输出?我已尝试将
2>/dev/null
附加到我的命令,但此重定向似乎没有像我最初希望的那样工作。

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

printf "Hello" 2> /dev/null >> a.txt
如果您还希望禁止来自正在运行的命令的错误,而不仅仅是来自启动之前执行的重定向,则此选项是正确的

如果只想抑制来自重定向本身的消息,而不想同时抑制来自实际执行的错误消息,则需要额外的一对重定向,以临时存储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(fd1)指向
    aa.txt
    ,stderr指向
    /dev/null
  • 2>&3
    将FD 3上的备份复制回FD 2,将stderr恢复到其原始目标,以便运行的程序可以记录错误
  • 3>&-
    删除备份,保留文件描述符表,如果我们什么都不做的话。(通常可以安全地忽略这一点——大多数表现良好的程序只会忽略非标准文件描述符的初始值,除非明确要求这样做)

回答得很好。值得注意的是,如果以交互方式运行,您可能希望简化为:
cmd 2>/dev/null>output 2>/dev/tty
cleer@那个家伙的评论是我所需要的全部,但我一定会记下来以备将来参考!非常感谢。顺便说一下,这是一个很棒的第一个问题!自给自足,同时保持简洁;格式良好,不是我们反复看到的常见问题,描述了您尝试过的内容&c.BTW,您是否希望您的程序仍然运行,而不是完全不被调用?对于
printf
,显然,如果它不能写入stdout,那么运行它是没有意义的;但是我可以想到一些情况,在这些情况下,可能会有您实际想要的其他副作用。@CharlesDuffy就我而言,这将是一个bash脚本,它隐藏了大部分输出,并使用print语句来解释所发生的事情的总体思路。此printf是if语句的一部分,如果写入失败,则会通知用户写入失败,并在退出前与我联系,代码为1.Gotcha。另外,信息和诊断信息通常应打印到stderr而不是stdout。这不仅仅是一个跟踪问题,还可以确保在stdout通过管道传输到其他地方时,日志仍然显示在正确的位置,并确保立即打印这些日志,而不是缓冲这些日志(当打印到非TTY目的地时,默认情况下标准输出是缓冲的——在这种情况下,为什么内容不会立即显示是常见问题)。