I'm analyzing two scripts with some behaviour I don't understand:
#/bin/bash
tijd=${1-60}
oud=`ls -l $MAIL`
while : ; do
   nieuw=`ls -l $MAIL`
   echo $oud $nieuw
   sleep $tijd
done | { read a b rest ; echo $a ; echo $b ; echo $rest ; }
The while loop in this script stops after one iteration.
#/bin/bash
tijd=${1-60}
oud=`ls -l $MAIL`
while : ; do
   nieuw=`ls -l $MAIL`
   echo $oud $nieuw
   sleep $tijd
done | cat
The while loop in this script is infinite.
What is the difference? I think it's something with the pipe and the brackets but I can't explain it.
Your loop with read after pipe is terminating after first iteration because of invocation of SIGPIPE signal which happens LHS of pipe writes to a pipe whose output is not read as there is no while loop around read on RHS).  YOur example with cat doesn't exit because cat continuously reads from input where as read terminates after reading one line.
To understand this behavior first reduce your example:
while : ; do pwd; done | { read -r line; echo $line; }
/Users/admin
So read terminated after first line. To verify this enable pipefail using:
set -o pipefail
and check exit status:
while : ; do pwd; done | { read -r line; echo "$line"; }
echo $?
141
Exist status 141 is due to SIGPIPE.
To fix this now change your read on RHS of pipe inside a while loop:
while : ; do pwd; sleep 5; done | { while read -r line; do echo "$line"; done; }
/Users/admin
/Users/admin
/Users/admin
And now you will not see command exiting at all since while read is continuously capturing all the data from LHS of pipe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With