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