#!/bin/sh
generate_data () {
shuf -i 0-1000 -n 10 -r
}
print_maximum () {
awk 'NR == 1 || m < $0 { m = $0 } END { print m }'
}
exec 3>&1
maximum=$(
generate_data |
tee /dev/fd/3 |
print_maximum
)
exec 3>&-
printf 'maximum = %d\n' "$maximum"
This passes some random numbers through tee, duplicating them to file descriptor 3 and to the standard output of tee. The standard output is read by print_maximum, which finds and outputs the largest number among the ones generated.
File descriptor 3 is initially opened as copy of the shell's standard output stream (with exec 3>&1), which means that when tee writes to it (by writing to /dev/fd/3), the data appears on the shell's standard output. That file descriptor is later closed (with exec 3>&-).
Note that the script uses /bin/sh as it does not need to use any bash-isms. With bash though, you'd be guaranteed that /dev/fd/3 was usable as file descriptor 3, and not reliant on that path being provided by the system.
Example run:
$ sh script
918
787
290
998
737
1000
845
374
497
809
maximum = 1000
To show that all output is generated on the script's standard output, I can show that it's possible to grep the generated data:
$ sh script | grep -F 0
100
807
maximum = 807
$ sh script | grep -F 0
440
207