a bash pipe command exit code rule
Solution 1
This is because the pipe takes the stdout and pipes it to the next command, what you want instead is the semicolon.
ls | grep -q foo; echo $?
This finished the ls
and grep
commands and then executes the echo
command.
Solution 2
The special variable $?
expands to the exit status of the most recently executed foreground pipeline. In your example, the | echo $?
is the most recently executed foreground pipeline, at that point the exit status of the command before the last |
is no longer accessible via $?
.
On a related note, you can use the exit code directly in conditional statements, for example:
if ls | grep -q foo; then echo success, there is foo; fi
Or, if you want to execute something on success,
you could chain the next command using &&
:
ls | grep -q foo && echo success
Related videos on Youtube
Chihaya
Updated on September 18, 2022Comments
-
Chihaya over 1 year
I was writing a simple script that checks the output of a command that if it displays a certain keyword. To see if it works, I was checking the command from the bash command line.
$ ls | grep -q foo $ echo $?
It displayed 1 or 0 depends on the command output and a grep parameter as I expected.
I get little lazy to type the command again, so I added
| echo $?
at the end of the command line.$ ls | grep -q foo | echo $?
Then regardless the command output, it always returns 0, even if the first part returns 1.
I guess this is normal behavior but I'd like to know why bash works this way.