Sample Header Ad - 728x90

Terminating the whole pipeline at once when its last process ends

0 votes
2 answers
139 views
Given the pipeline printf '%s\n' 1 2 3 4 5 6 7 8 9 | while read -r num do echo "$num" > /dev/stderr echo "$num" done | while read -r num do echo $(( $num * 10 )) [ "$num" -eq 5 ] && break done bash will output something like 1 2 10 3 20 4 30 5 40 50 6 7 8 9 to the terminal. The places in the single digit sequence where the two-digit numbers are inserted will be different each time you run the pipeline because of how buffering and/or scheduling work. I would like to have the first while-read loop terminate at once when the second loop terminates; that is, I want the pipeline to not output any single digits after it has printed the number 50. I tried using the command stdbuf -o0 to set the buffer to 0, as suggested by this article and Force line-buffering of stdout in a pipeline . stdbuf -o0 printf '%s\n' 1 2 3 4 5 6 7 8 9 | while read -r num do echo "$num" > /dev/stderr echo "$num" done | while read -r num do echo $(( $num * 10 )) [ "$num" -eq 5 ] && break done hoping to achieve this, but the printf command and the first loop still stay alive and can print their output after the last loop has printed the number 50. I also tried set -o pipefail and turning the second loop into the function: g () { while read -r num do echo $(( $num * 10 )) [ "$num" -eq 5 ] && break done return 1 } and modifying the pipeline accordingly: printf '%s\n' 1 2 3 4 5 6 7 8 9 | while read -r num do echo "$num" > /dev/stderr echo "$num" done | g (and then calling set +o pipefail afterwards), but that also fails to achieve what I want. Apparently there is some fundamental error in my understanding of how pipelines and buffering work. Please explain to me what I am missing and how I can get the output I want. "Turning Off Buffer in Pipe With stdbuf at Baeldung on Linux"
Asked by fuumind (449 rep)
Jun 4, 2024, 08:58 AM
Last activity: Jun 17, 2024, 07:37 AM