whenever you do
mycmd | grep mytext
the return code of command got lost, $? point to the return code of grep. Back in time I posted https://laurentschneider.com/wordpress/2009/05/return-code-before-grep.html
(
(
(
mycmd
echo $? >&3
) |grep mytext >&4
) 3>&1 |(read x;exit $x)
)4>&1
this did work like a charm for decades.
But earlier this year I found this sexy syntax
mycmd > >(grep mytext)
While it may abuse your memory, especially on legacy/ancient operating systems, it is more understandable. A little bit. Maybe. YMMV.
Last week I discovered also, while ansiblelinting my code
set -o pipefail mycmd | grep mytext
It looks better but it is a disgusting hack. I tested a bit and very quickly decided to add
skip_list: - 'risky-shell-pipe'
in my .ansible-lint file.
pipefail has an annoying handling of SIGPIPE.
# ( set -o pipefail; head -c 95698 /tmp/xxx | grep -q .; echo $? ) 141 # ( set -o pipefail; head -c 95698 /tmp/xxx | grep -q .; echo $? ) 0 # ( set -o pipefail; head -c 95698 /tmp/xxx | grep -q .; echo $? ) 0 # ( set -o pipefail; head -c 95698 /tmp/xxx | grep -q .; echo $? ) 0
Random absolutely unusable stuff… avoid!
SIGPIPE is documented as :
On a last note, pipes must have a reader and a writer. If a process tries to write to a pipe that has no reader, it will be sent the SIGPIPE signal from the kernel.
so when head stops writing, grep may no longer read and the pipe may get a death signal. But it is not consistent.