bash - 如何在 shell 管道中使用不同的文件描述符?

标签 bash unix sh pipeline file-descriptor

我正在处理一个脚本,它首先调用一个嘈杂的程序(在 stdoutstderr 上有很多诊断)程序,然后用其他工具处理它的输出.

该程序的冗长使得无法简单地将其标准输出发送到管道,因此目前我们使用临时文件——我想结束这种做法。

代替 /tmp/foo,我们可以要求程序将数据写入 /dev/fd/N —— 它会的,没问题(它例如,不需要寻找文件)。

它当前发送到 stdoutstderr 的噪音,可以继续到那里——运算符(operator)已经习惯看到它,如果它消失了,就会报警。 ..

但是我如何安排描述符 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 系列 shell 一起使用。

关于bash - 如何在 shell 管道中使用不同的文件描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66080381/

相关文章:

shell - -f 在解释器定义中是什么意思 : ! #/bin/awk -f

unix - Unix 内核如何转换文件偏移量?

linux - Impala-shell 命令参数列表太长

windows - 好奇执行二进制

bash - Jenkins 无法访问 shell 别名

java - 如何从 shell 脚本调用 Java 程序,而不让 shell 脚本等待程序完成执行?

ruby - 为什么 bash -l -c "CMD"让 ruby 找到我的 gem ?

linux - BASH CURL为POST请求传递json数据

java - 警告 : Couldn't read data from file "image.jpg", 这会导致空 POST

java - 从java在远程机器上运行linux命令