如何解决如何在 shell 管道中使用不同的文件描述符?
我正在处理一个脚本,该脚本首先调用一个嘈杂的(对 stdout
和 stderr
进行大量诊断)程序,然后使用其他工具处理其输出。
程序的冗长使得无法简单地将其标准输出发送到管道,因此目前我们使用临时文件——我想结束这种做法。
代替/tmp/foo
,我们可以要求程序将数据写入/dev/fd/N
——它会,没问题(它不需要seek
文件,例如).
它当前发送给stdout
和stderr
的什么噪音,可以继续去那里——操作员已经习惯了看到它,如果它消失了就会惊慌……
但是我如何安排描述符 N
存在并被发送到下一个程序的 stdin
中?
noisy -o /dev/fd/N ?????| filter -i /dev/stdin
如果这需要 bash
,那就这样吧,但我当然更喜欢适合整个 sh 系列的解决方案。
解决方法
如果我正确理解了您的问题,那么您就有了一个将噪声写入标准输出和标准错误的程序,并将有用的数据写入使用 -o
选项指定的文件。您希望标准输出和标准错误保持原样,但将有用数据通过管道传输到过滤器程序中,而不是将其写入文件。
使用 Bash 执行此操作的最简单方法是使用进程替换(请参阅 ProcessSubstitution - Greg's Wiki):
noisy -o >(filter -i /dev/stdin)
请注意,进程替换在某些 sh 系列 shell 中不可用,它在某些(不常见)平台上的 Bash 中不可用,并且无法获取之前使用 Bash 进行进程替换创建的进程的退出状态4.4 版。
另一种可能的方法来做(我认为)你想要的:
exec 3>&1
{ exec 4>&1; noisy -o /dev/fd/4 >&3 ; } | filter -i /dev/stdin
-
exec 3>&1
使文件描述符 3 引用“真实”标准输出。 -
exec 4>&1
(因为它在管道第一阶段的进程中运行)使文件描述符 4 指向管道中下一阶段的输入。 -
noisy ... >&3
强制noisy
的标准输出转到“真实”标准输出。 - 写入
/dev/fd/4
(至少在 Linux 上)会写入管道的下一个阶段。
我只用 Bash 测试过它,但我认为它应该适用于其他 sh-family shell。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。