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