kward / shflags

shFlags is a port of the Google gflags library for Unix shell.
Apache License 2.0
283 stars 45 forks source link

source'ing shflags causes script to fail when `set -euo pipefail` is used #57

Closed andresoto-x closed 1 year ago

andresoto-x commented 1 year ago

When writing a bash script, it's often beneficial to run set -euo pipefail. This is characterized as Bash Strict Mode .

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
kward commented 1 year ago

set -e support was fixed in HEAD for Issue #9. I'll do some checks on set -o pipefail.

kward commented 1 year ago

Chatted offline with the submitter and they confirm the bug is fixed at HEAD. Will prioritize a new release this week.