I want to pass stdin to two different processes. What are some nice clean ways to do this?
(I'm proposing a tempfile based way as an answer below, but maybe there are better ways?)
GitHub's "git lfs pre-push" pre-push hook reads stdin. I want to install a second pre-push check, e.g. the WIP check I find in pre-push.sample. This means I need to save stdin in some reasonable way, so that the commits can be read by both "git lfs pre-push" and by the "while read local_ref local_sha remote_ref remote_sha" loop.
You could use tee
with an output process substitution.
Here I'll put the individual check code into functions for clarity:
check1() {
git lfs pre-push "$@"
}
check2() {
while read -ra variables; do
: ...
done
}
# redirecting to /dev/null so you don't get the original input as well
tee >(check1) >(check2) >/dev/null
I'm not sure of the limitations, but you can do an arbitrarily large number of checks this way:
tee >(check1) \
>(check2) \
>(check3) ...
A demo:
check1() { while IFS= read -r n; do echo $((n*5)); done; }
check2() { while IFS= read -r line; do echo ">>>$line<<<"; done; }
seq 101 100 1101 | tee >(check1) >(check2) >/dev/null
output
505
>>>101<<<
1005
1505
2005
2505
3005
3505
>>>201<<<
4005
4505
>>>301<<<
5005
>>>401<<<
5505
>>>501<<<
>>>601<<<
>>>701<<<
>>>801<<<
>>>901<<<
>>>1001<<<
>>>1101<<<
Since both checks are running in subshells, the output order is indeterminate.
This technique is also demonstrated in the
info tee
documentation.