Pinaki Mukherjee
Pinaki Mukherjee

Reputation: 1656

Shell script - exiting script if variable is null or empty

I am expecting to use the below variable in my bash script but in case if this is empty or null what would be the best way to handle it and exit from script.

tag=$1  

I am seeing answers with 'set -u'. I know this will work but is this good for production environment?

Upvotes: 27

Views: 44042

Answers (7)

Micah Smith
Micah Smith

Reputation: 4453

If you want to test that a variable is non-empty, you can do this:

if [ -z "$tag" ]; then
    echo "variable tag is empty so program will exit now!"
    exit 1
fi

From the manual for test:

-z STRING

the length of STRING is zero

Given that you are using the positional arguments to the script, you could also test the number of arguments you receive by looking at $#.

Upvotes: 23

Dan Christian
Dan Christian

Reputation: 440

I rather liked how Perl uses "die" and it's easy to do something similar in shell.

# Print (optional) error message and exit
# Usage: die [[msg] exit_status]
die() {
    [[ -n "$1" ]] && echo "$1"
    [[ -n "$2" ]] && exit $2 || exit 1
}

[[ -n "$tag" ]] || die "Need a tag argument.  Use $0 --help for details"

This assumes bash or Korn shell, but can be converted to classic Bourne shell by changing [[]] to [].

Upvotes: 1

Pav K.
Pav K.

Reputation: 2858

No one suggested :? option.

If you want to make sure the variable is set and not null:

SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}

Will exit immediately with code 2 & print a message:

/entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.

Upvotes: 10

Pinaki Mukherjee
Pinaki Mukherjee

Reputation: 1656

The following test ensure that a variable is either Null or has a value assigned to it.The double quotes are very important and must be used!

VAL= # Creates a NULL variable
if [[ -z "$VAL" && "$VAL" = ’’ ]]
then
echo "The VAL variable is NULL"
fi
or
VAL=25
if [[ ! -z "$VAL" && "$VAL" != ’’ ]]
then
echo "The VAL variable is NOT NULL"
fi

Upvotes: 0

tripleee
tripleee

Reputation: 189297

There is a built-in operator for requiring that a variable is set. This will cause the script to exit if it isn't.

tag=${1?Need a value}

Commonly this is used with the : no-op near the beginning of the script.

: ${1?Need a value}

The conflation of "unset or empty" is somewhat different. There is no similar construct for exiting on an empty but set value, but you can easily use the related syntax ${var:-default} which expands to $var if it is set and nonempty, and default otherwise. There is also ${var-default} which only produces default if the variable is properly unset.

This can be particularly useful when you want to use set -u but need to cope with a possibly unset variable:

case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac

I somewhat prefer case over if [ "${var-}" = '' ], mainly because it saves me from having to wrap double quotes around ${var-}, and the pesky case of a value in $var which gets interpreted as an option to [ and gives you an error message when you least expect it. (In Bash, [[ doesn't have these problems; but I prefer to stick to POSIX shell when I can.)

Upvotes: 42

chepner
chepner

Reputation: 530823

Use pattern matching to detect if the value consists only of whitespace:

pattern=$'*( |\t)'
if [[ $1 = $pattern ]]; then
    echo "First parameter has no non-whitespace characters"
    exit 1
fi

The $'...' quoting makes it easier to add a tab to the string. The extended pattern *(...) matches 0 or more the patterns inside the parentheses (similar to regex ( |\t)*). The pattern is assigned to a variable because = performs exact string matching if any part of its right-hand operand is quoted, so we perform the quoting beforehand to make it easier to set the value.

Upvotes: 1

Arkadiusz Drabczyk
Arkadiusz Drabczyk

Reputation: 12363

I am not sure whether you want to detect if a variable is unset or empty. These are 2 different things. Specifically, a variable can be set but be empty:

$ var=""
$ if [ -z "$var" ]; then echo empty; fi
$ empty

The same is going on here:

#!/usr/bin/env bash

set -u
echo $1

Test:

$ ./test.sh
./test.sh: line 4: $1: unbound variable
$ ./test.sh ""

$

Or here:

#!/usr/bin/env bash

tag=${1?Need a value}
echo $tag

Test:

$ ./se.sh
./se.sh: line 3: 1: Need a value
$ ./se.sh ""

$

Other posters have presented correct ways to detect an unset and empty variable. Personally I like this way of detecting empty and unset variables:

#!/usr/bin/env bash

if [ "$1"A = A ]
then
    echo variable is empty or unset
fi

Test:

$ ./empty.sh ""
variable is empty or unset
$ ./empty.sh
variable is empty or unset
$ ./empty.sh 1
$

Upvotes: 4

Related Questions