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 Edit: as chepner pointed out, tee by default inherits the shell's stdin.<&0
for the first tee to get the script'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
tee
s can be pipe chained like this to duplicate your input(but don't copy the(initial<&0
stdin redirection from the initial one)<&0
has been removed)