如何在bash脚本中将标准输入(stdin)复制到多个子进程?

时间:2015-10-28 23:02:47

标签: bash shell io-redirection

我想将stdin重定向到多个脚本,以便测试一个开发中的git hook,同时保留旧的。我知道我应该以某种方式使用tee,我不知道如何使用bash的基本><和管道|重定向功能来执行此操作。此外,如何重定向脚本的stdin?我不想使用read,因为它一次只能读取一行,而且我必须为每一行重新执行所有子流程。

1 个答案:

答案 0 :(得分:3)

您可以将tee与普通文件(可能是mktemp的临时文件)一起使用,然后cat将这些文件用于各种脚本。更直接地说,您可以使用mkfifo创建的命名管道替换这些普通文件。但是,您可以使用Bash强大的流程替换>( cmd )<( cmd )功能在一个管道中执行此操作,以替换您的子流程所需的文件tee

使用<&0获取第一个tee来获取脚本的stdin。编辑:正如chepner指出的那样,tee默认继承shell的stdin。< / p>

最终结果是这个包装脚本:

#!/bin/bash
set +o pipefail
tee >(testscipt >> testscript.out.log 2>> testscript.err.log) | oldscript

一些注意事项:

  • 使用set +o pipefail 禁用 Bash的pipefail功能(如果之前已启用)。启用后,Bash将报告管道内的错误。禁用时,它只会报告最后一个命令的错误,这就是我们在这里要保持我们的testscript对包装器不可见的(我们希望它的行为就好像它只是调用oldscript以避免中断。
  • 重定向testscript的stdout,否则它将被转发到管道中的下一个命令,这可能不是你想要的。当你正在使用时,重定向stderr。
  • 任何数量的tee都可以像这样进行管道链接以复制输入(但不要复制<&0 stdin重定向从初始值 (初始<&0已被删除)