Why exit code 141 with grep -q?
Can someone explain why I get exit code 141 from the below?
#!/usr/bin/bash
set -o pipefail
zfs list | grep tank
echo a ${PIPESTATUS[@]}
zfs list | grep -q tank
echo b ${PIPESTATUS[@]}
cat /etc/passwd | grep -q root
echo c ${PIPESTATUS[@]}
I get
...
a 0 0
b 141 0
c 0 0
From my understanding exit code 141 is a failure, but the line above gives zero, so it should be success, I would say.
Solution 1:
This is because grep -q
exits immediately with a zero status as soon as a match is found. The zfs
command is still writing to the pipe, but there is no reader (because grep
has exited), so it is sent a SIGPIPE
signal from the kernel and it exits with a status of 141
.
Another common place where you see this behaviour is with head
. e.g.
$ seq 1 10000 | head -1
1
$ echo ${PIPESTATUS[@]}
141 0
In this case, head
read the first line and terminated which generated a SIGPIPE
signal and seq
exited with 141
.
See "The Infamous SIGPIPE Signal" from The Linux Programmer's Guide.
Solution 2:
I'm not familiar with zfs list
, but I guess it complains about its standard output being closed - grep -q
exits immediately when a match is found, unlike grep
.