Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'd like to make sure that at a certain point of a script, after sourceing a configuration file, several variables are set and, if they are not, to stop execution, telling the user about the missing variable. I have tried

for var in $one $two $three ; do
    ...

but if for example $two is not set, the loop is never executed for $two. The next thing I tried was

for var in one two three ; do
    if [ -n ${!var} ] ; then
        echo "$var is set to ${!var}"
    else
        echo "$var is not set"
    fi
done

But if two is not set, I still get "two is set to" instead of "two is not set".

How can I make sure that all required variables are set?

Update/Solution: I know that there is a difference between "set" and "set, but empty". I now use (thanks to http://stackoverflow.com/a/16753536/3456281 and the answers to this question) the following:

if [ -n "${!var:-}" ] ; then

so, if var is set but empty, it is still considered invalid.

share|improve this question
1  
You can also add set -u to the beginning of your script to terminate it immediately when an unset variable is used. –  n.st 11 hours ago
add comment

4 Answers

up vote 5 down vote accepted

Quoting error.

if [ -n "${!var}" ] ; then

For the future: Setting

set -x

before running the code would have shown you the problem. Instead of adding that to the code you can call your script with

bash -vx ./my/script.sh
share|improve this answer
    
This works, but what is happening with/whithout quotes? Is my general approach correct the first place? –  Jasper 12 hours ago
    
Yeah, that's precognitive: I answered the question before it was asked... 8-) –  Hauke Laging 12 hours ago
2  
@Jasper You should always quote variables. That does not cost more time than thinking about whether this is necessary every time. But it avoids the errors. –  Hauke Laging 12 hours ago
add comment

Only thing you need are quotes in your test:

for var in one two three ; do
    if [ -n "${!var}" ] ; then
        echo "$var is set to ${!var}"
    else
        echo "$var is not set"
    fi
done

Works for me.

share|improve this answer
add comment

I think if you mean not set, so the variable must never be initialized. If you use [ -n "${!var}" ], so the empty variable like two="" will be failed, while it is set. You can try this:

one=1
three=3

for var in one two three
do
    declare -p $var > /dev/null 2>&1 \
    && echo $var is set to ${!var} \
    || echo $var is not set
done
share|improve this answer
add comment

You can add

set -u

to the beginning of your script to make it terminate when it tries to use an unset variable.

A script like

#!/bin/sh
set -u
echo $foo

will result in

script.sh: 3: script.sh: foo: parameter not set

If you're using bash instead, the error will look like this:

script.sh: line 3: foo: unbound variable

share|improve this answer
    
And in your opinion this makes which sense for run time checks? –  Hauke Laging 9 hours ago
    
@HaukeLaging I don't quite follow you — set -u prevents exactly the kind of error the OP is trying to avoid and (in contrary to all other solutions) isn't limited to a specific set of variables. It is in fact a useful precaution for almost all shell scripts to have them fail safely instead of doing unexpected things when a variable is unset. This article is a handy reference on the topic. –  n.st 9 hours ago
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.