Brian Chrisman
Brian Chrisman

Reputation: 3704

File descriptor duplication

I'd like to feed multiple copies of stdin to different stdins/FDs in bash. Example:

for host in $hosts; do
  exec_magic_stdin_dupe {FH}
  ssh $host someProgram <&$FH
done

I've used GNU parallel a bit, but I've got some caveats with it and really thought this should be something bash can do alone. The only way I've found that's anything like this is to 'tee' it with subshell replacements like:

tee >(ssh $hostOne someProgram) >(ssh $hostTwo someProgram) ... > /dev/null

But that means I've got to perform some sort of loop creating a big 'tee' command and then execute it via 'eval' (or similar).

I could do it by managing my own fifos as well, but that's not a particularly preferable solution either.

All the above can work. I just want to verify that I'm not missing some way to implement 'exec_magic_stdin' before implementing one of those solutions.

Upvotes: 1

Views: 268

Answers (1)

chepner
chepner

Reputation: 532053

Recursion helps here; you can pipe the output of one tee into the input of the next, until you are out of hosts. Each call to recFunc "peels off" one host. tee passes its input to both a call to ssh and to the next invocation of recFunc, which does nothing if it receives no arguments. The initial call to recFunc gets a list of host names as arguments and its standard input from the file you want to duplicate.

recFunc () {
    if (( $# )); then
        tee >(ssh "$1" someProgram) | recFunc "${@:2}"
    fi
}

hosts=(hostOne hostTwo hostThree ... )
recFunc "${hosts[@]}" < inputfile

Upvotes: 2

Related Questions