62

I want to check, if multiple variable are set or not, if set then only execute the script code, otherwise exit.

something like:

if [ ! $DB=="" && $HOST=="" && $DATE==""  ]; then
  echo "you did not set any variable"
   exit 1;
else
  echo "You are good to go"
fi      
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
ramesh.mimit
  • 9,445
  • 4
  • 21
  • 23
  • for check variable has value or not [ -z $a -a -z $b -a -z $c ] && echo "has not value" || echo " ok good to go!" – Soheil Mar 26 '15 at 13:14

6 Answers6

113

You can use -z to test whether a variable is unset or empty:

if [[ -z $DB || -z $HOST || -z $DATE ]]; then
  echo 'one or more variables are undefined'
  exit 1
fi

echo "You are good to go"

As you have used the tag, I've used an extended test [[, which means that I don't need to use quotes around my variables. I'm assuming that you need all three variables to be defined in order to continue. The exit in the if branch means that the else is superfluous.

The standard way to do it in any POSIX-compliant shell would be like this:

if [ -z "$DB" ] || [ -z "$HOST" ] || [ -z "$DATE" ]; then
  echo 'one or more variables are undefined'        
  exit 1
fi

The important differences here are that each variable check goes inside a separate test and that double quotes are used around each parameter expansion.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • Thanks! I guess you could also use `-o` to combine the tests in a single predicate, rather than using || and three separate `[` calls? – BeeOnRope Feb 06 '17 at 20:13
  • 2
    @BeeOnRope The recommendation is to [avoid using `-a` and `-o`](http://pubs.opengroup.org/onlinepubs/009696899/utilities/test.html) (see the _Application Usage_ section), especially when dealing with variables that could be user-defined. – Tom Fenech Feb 06 '17 at 20:58
  • Thanks for mentioning the "quotes" difference. I didn't even see that diff in my code :( – ninhjs.dev Apr 27 '21 at 12:59
21

If you are ok with writing a function for this purpose, it can be pretty convenient.

This solution uses the ${!VAR_NAME} syntax to check whether the variable is empty and has the added benefit of telling you which variable names are empty.

check_vars()
{
    var_names=("$@")
    for var_name in "${var_names[@]}"; do
        [ -z "${!var_name}" ] && echo "$var_name is unset." && var_unset=true
    done
    [ -n "$var_unset" ] && exit 1
    return 0
}

# Usage for this case
check_vars DB HOST DATE
echo "You are good to go" 
Bromate
  • 430
  • 3
  • 5
4

I wound up using variable-variables to loop through an easily managed HEREDOC list of variable names:

# Ensure non-empty values.
# Loop through HEREDOC, test variable-variable isn't blank.
while read var; do
  [ -z "${!var}" ] && { echo "$var is empty or not set. Exiting.."; exit 1; }
done << EOF
KUBE_NAMESPACE
DOCKER_REGISTRY
DOCKER_DEPLOY_USER
DOCKER_DEPLOY_PASSWORD
DOCKER_DEPLOY_EMAIL
EOF
Joe Still
  • 141
  • 1
  • 4
1

You can check it also by put the variables name in a file

DB=myDB
HOST=myDB
DATE=myDATE

then test them if currently empty or unset

#!/bin/bash
while read -r line; do
    var=`echo $line | cut -d '=' -f1`
    test=$(echo $var)
    if [ -z "$(test)" ]; then 
        echo 'one or more variables are undefined'
        exit 1
    fi
done <var.txt
echo "You are good to go"
eQ19
  • 9,880
  • 3
  • 65
  • 77
1

Nice solution from @joe.still ! improvement is to exit after checking all variables

i=0
while read var; do
  [ -z "${!var}" ] && { echo "$var is empty or not set. Exiting.."; let i=i+1; }
done << EOF
KUBE_NAMESPACE
DOCKER_REGISTRY
DOCKER_DEPLOY_USER
DOCKER_DEPLOY_PASSWORD
DOCKER_DEPLOY_EMAIL
EOF

if [ $i -gt 0 ]; then
  echo $i
  echo "exiting"
  exit 1
fi
khancell
  • 329
  • 2
  • 4
0

Good Day Everyone. I've personally used this method in my bash scripts. Verified works on bash 4.4 and later in Ubuntu, openSUSE, and ClearLinux.

Can RHEL|CentOS|Alma and Arch Based users let me know it it works fine for you?

( [ "$VAR1""$VAR2""$VAR3""$VAR4""$VAR5" ] && echo -e " Warning: StackIsNotClear" ) || { echo -e " GoodNews:  StackIsClear"; }