When writing a bash script, it's often beneficial to run set -euo pipefail. This is characterized as Bash Strict Mode .
set -e instructs bash to immediately exit if any command has a non-zero exit status.
set -u instructs bash causes the program to exit immediately if there are any unset variables
set -o pipefail prevents errors in a pipeline from being masked. If any command in a pipeline fails, that return code is used as the return code of the whole pipeline.
Here's an example. I took the script from the Quick Start guide, and simply added set -euo pipefail at the very top.
#!/bin/sh
set -euo pipefail
# Source shflags and cancel execution if we can't find shflags.
# shellcheck source=./tools/install_shflags.sh
source /usr/bin/shflags || exit 1
# define a 'name' command-line string flag
DEFINE_string 'name' 'world' 'name to say hello to' 'n'
# parse the command-line
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"
# say Hello!
echo "Hello, ${FLAGS_name}!"
When I run the program, it immediately exits. Here's what I see
$ ./hello_world.sh
$
When I comment out the set line, I get:
$ tools/hello_world.sh --name test
Hello, test!
If I move set -euo pipefail after we source the shflags library, the program works as intended:
#!/bin/sh
# Source shflags and cancel execution if we can't find shflags.
# shellcheck source=./tools/install_shflags.sh
source /usr/bin/shflags || exit 1
set -euo pipefail # now we have the line here
# proceed with the normal program ...
This is the spirit of me filing this issue. Additionally, this behavior Im describing also occurs when you simply use set -e. set -euo pipefail seems unnecessary in this case. What this indicates to me is source'ing the shflags library returns a non-zero exit status and causes the entire program to fail. This
My Installation Process
Note, the way Im installing shflags onto my machine is like so:
#!/bin/bash
# This script installs the [shflags], https://github.com/kward/shflags, library. This library
# is a port of Google's flags library for Unix shell. shflags is simply a library that you include
# into an existing shell, so you can define shell command line flags.
set -euo pipefail
# Install shflags library in /opt and create a symlink to the implementation file
if [[ ! -d /opt/shflags-1.2.3 ]]; then
wget -nH https://github.com/kward/shflags/archive/refs/tags/v1.2.3.tar.gz
tar xzfp v1.2.3.tar.gz
rm v1.2.3.tar.gz
sudo mkdir -p /opt
sudo mv shflags-1.2.3 /opt
sudo chown -R root.root /opt/shflags-1.2.3
# Adds a symlink to the implementation file, which allows us to run `source shflags` instead of running
# `source /opt/shflags-1.2.3/src/shflags`
sudo ln -s /opt/shflags-1.2.3/shflags /usr/bin/shflags
fi
When writing a bash script, it's often beneficial to run
set -euo pipefail
. This is characterized as Bash Strict Mode .set -e
instructs bash to immediately exit if any command has a non-zero exit status.set -u
instructs bash causes the program to exit immediately if there are any unset variablesset -o pipefail
prevents errors in a pipeline from being masked. If any command in a pipeline fails, that return code is used as the return code of the whole pipeline.Here's an example. I took the script from the Quick Start guide, and simply added
set -euo pipefail
at the very top.When I run the program, it immediately exits. Here's what I see
When I comment out the
set
line, I get:If I move
set -euo pipefail
after we source theshflags
library, the program works as intended:This is the spirit of me filing this issue. Additionally, this behavior Im describing also occurs when you simply use
set -e
.set -euo pipefail
seems unnecessary in this case. What this indicates to me issource
'ing theshflags
library returns a non-zero exit status and causes the entire program to fail. ThisMy Installation Process
Note, the way Im installing shflags onto my machine is like so: