如何暂时禁用bash脚本中的stdout或stderr?
当然最常见的方法是将stdout或stderr重定向到/ dev / null .
但在某些系统上,/ dev / null对于普通用户来说可能是不可写的 .
我正在编写一些旨在可移植的脚本,所以我不喜欢使用/ dev / null
一些博客/帖子说>& - 可以关闭stdout,但是当我在bash终端中尝试回显123>& - 时,它刚刚失败并显示消息"bash: echo: write error: Bad file descriptor"
当然我可以通过将stdout或stderr重定向到这样的tmp文件来实现:
some_command> / tmp / null
但我想要的是更多"elegant"方式
我想也许我可以通过使用这样的管来实现这一点:
some_command | :
但通过这种方式,它可能会“污染”原始命令的退出代码
2 回答
这是一种可能的方法来做你想要的:
这会暂时将
stdout
发送到新文件句柄3
并将stderr
重定向到stdout
,以便stderr
管道进入命令(在本例中为:
) . 然后将新文件句柄路由回stdout
. 这些避免将my_cmd
的my_cmd
输入:
.-
在使用后关闭句柄 .要在上面检查
my_cmd
的存在状态,请检查环境变量$PIPESTATUS[0]
.$PIPESTATUS
是一个bash
环境数组变量,它保存最后一个管道中每个管道命令的退出状态 .我认为真正正确的答案是调查为什么
/dev/null
不是世界可写的 . 不是这样的是非标准的系统配置,可能会导致系统问题 . 相比之下,上述解决方法有点混乱 .根据我之前写的内容和@nos上面的评论,这是一个例子:
(假设您当前目录中没有名为'zzz'的文件,并且' . '可读)
管道成功并以静默方式失败并维护退出代码 . 请注意,您可能仍然可以创建一个管道示例,但这不会产生所需的结果 . 我还没想出一个,但这并不意味着它不在那里 . 正如许多人已经指出的那样,最好的答案是修复系统,使/ dev / null是世界可写的 .
EDIT :将/ bin / sh更改为/ bin / bash,虽然这可能不是针对真正的Bourne Shell进行测试的,但我决定谨慎行事 .
EDIT :另一个脚本,显示了几种不同的重定向,并使用了
2>&1 |
的|&
快捷方式 . 如果你运行它,你会发现一些ls
失败返回141退出状态而不是预期的2.这是一个破坏的管道退出状态,但仍然代表一个失败 .当我试图摧毁stdout但保持stderr时,我使用了两个子shell . 你可以在没有外层的情况下做到这一点 . 事实上,这可能会更好 . 您可以获得1退出状态,而不是获得损坏的管道错误 .