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
Last activity: Jun 17, 2024, 07:37 AM