The set command is an important tool in the Linux shell. It provides mechanisms for script debugging, control of variables, and error termination policies. However, some of its options may cause an error if not used correctly.
In this tutorial, we’ll look at the pipefail option and learn how to avoid errors when using it.
2. Why Do We Use pipefail?
Each Bash pipeline has an exit status. This status provides useful information about how the pipeline terminated.
However, the exit status may be different based on our needs.
2.1. Return Exit Code of the Last Command
By default, the exit status of a pipeline is based on the return value of the last command in this pipeline. This is true even if a previous command in the pipeline failed.
To illustrate how this mechanism works, let’s consider the following pipeline:
$ nonexistingcommand | echo nonexistingcommand: command not found $ echo $? 0
We have a non-existing command piped to the simple echo command. Consequently, the exit status of the pipeline is 0 because the status of the echo command is 0.
2.2. Return Exit Code of Failed Command
Another way is to enable the pipeline to return its exit status based on the last failed command. This is useful for situations when we need more information about the failed command in the pipeline. To enable this option, we use the set -o pipefail command.
Now, let’s enable the pipefail option and see how it affects the exit status:
$ set -o pipefail $ nonexistingcommand | echo nonexistingcommand: command not found $ echo $? 127
We now have the exit status 127 (command not found) resulting from our non-existing command.
3. The “Illegal option -o pipefail” Error
Now that we know why we may need the pipefail option, let’s focus on the possible issues with it and how to avoid them.
First, let’s create a simple Bash script containing the set -o pipefail command:
$ cat script.sh #!/bin/bash set -o pipefail
Then, let’s run this script:
$ sh script.sh script.sh: 2: set: Illegal option -o pipefail
We can see the error Illegal option -o pipefail. Notably, this error happens on most vanilla Ubuntu systems and may differ for other distributions.
4. How to Avoid the Error
The above error happens because we use the sh command to run our script. On Ubuntu, sh is a symbolic link pointing to /bin/dash.
However, the pipefail option is available only in the Bash shell. So, to run it correctly, we should replace sh with bash:
$ bash script.sh
This time, there’s no error.
Another option is to make the script executable and run it as a Linux command:
$ chmod +x script.sh ./script.sh
For this method, we should double-check that the script has the correct shebang #!/bin/bash. Otherwise, the error may persist.
5. Preliminary Machine Checks
There’s a way to check if we’d see the same error on a given machine. To do that, we need to check whether sh is a symbolic link to Dash on the machine in question.
Let’s use find to check that:
$ find /bin/sh -type l -ls 1696 0 lrwxrwxrwx 1 root root 4 Apr 4 2022 /bin/sh -> dash
The find command above prints all symbolic links for the /bin/sh file. In the last column, we can see that /bin/sh points to Dash. This means that we can’t use sh to run the set -o pipefail command on this machine.
In this article, we learned when the pipefail option of the set command can cause problems.
Firstly, we briefly recalled how pipefail can help in debugging pipelines. Then, we looked at the “Illegal option -o pipefail” error and found out its origin, as well as how to avoid this error in the future. Finally, we learned how to check whether we’d see the error on a given machine.