When chaining commands in Bash using the pipe ‘|’ separator, the commands execute in sequence, with the output of the first command being used as the input to the second command.
When running a single Bash command, it is possible to detect if an error has occurred by examining the ‘$?’ built-in Bash variable directly after the command has completed. A zero ‘0’ return value means success, a non-zero return value means that an error has occured.
For example, trying to write output to a new file in the root of the file system.
bash ~$ echo "Create a file with one line in it" > /new-file.txt -bash: /new-file.txt: Permission denied bash ~$ echo $? 1
Whereas writing a file to your home path will succeed as expected.
bash ~$ echo "Create a file with one line in it" > ~/new-file.txt bash ~$ echo $? 0
But what happens if an error occurs when executing a command within a piped list of commands? Well in this case, the default is for the last command to set the return value for the entire command chain.
bash ~$ cat /new-file.txt | wc cat: /new-file.txt: No such file or directory 0 0 0 bash ~$ echo $? 0
This can be overridden by setting the pipefail Bash option.
bash ~$ set -o pipefail bash ~$ cat /new-file.txt | wc cat: /new-file.txt: No such file or directory 0 0 0 bash ~$ echo $? 1
This can be extremely useful if you regularly chain commands together, as the return value can be used to display a message to the user indicating an issue has occurred within the command chain.