How can I duplicate standard input (stdin) to multiple subprocesses in a bash script? How can I duplicate standard input (stdin) to multiple subprocesses in a bash script? shell shell

How can I duplicate standard input (stdin) to multiple subprocesses in a bash script?


You could use tee with normal files (possibly temp files via mktemp), then cat those files to your various scripts. More directly, you could replace those normal files with Named Pipes created with mkfifo. But you can do it in one pipe using Bash's powerful Process Substitution >( cmd ) and <( cmd ) features to replace the file tee expects with your subprocesses.

Use <&0 for the first tee to get the script's stdin. Edit: as chepner pointed out, tee by default inherits the shell's stdin.

The final result is this wrapper script:

#!/bin/bashset +o pipefailtee >(testscipt >> testscript.out.log 2>> testscript.err.log) | oldscript

Some notes:

  • use set +o pipefail to disable Bash's pipefail feature if it was previously enabled. When enabled, Bash will report errors from within the pipe. When disabled, it will only report errors of the last command, which is what we want here to keep our testscript invisible to the wrapper (we want it to behave as if it was just calling oldscript to avoid disruption.
  • redirect the stdout of testscript, otherwise it'll be forwarded to the the next command in the pipeline which is probably not what you want. Redirect stderr too while you're at it.
  • Any number of tees can be pipe chained like this to duplicate your input (but don't copy the <&0 stdin redirection from the initial one) (initial <&0 has been removed)