3

In a bash script, I'm trying to test for the existence of a variable. But no matter what I do, my "if" test returns true. Here's the code:

ignored-deps-are-not-set () { if [ -z "${ignored_deps+x}" ] then return 0 fi return 1 } ignored_deps=1 ignored-deps-are-not-set echo "ignored-deps function returns: $?" if [ ignored-deps-are-not-set ] then echo "variable is unset" else echo "variable exists" fi 

Here is the output as written:

ignored-deps function returns: 1 variable is unset 

And the output when I comment out the line where ignored_deps is set.

ignored-deps function returns: 0 variable is unset 

No matter what, it says the variable is unset. What am I missing?

2
  • - is not a valid char in a variable name. How is this "ignored-deps-are-not-set" name allowed? Commented Sep 22, 2011 at 19:44
  • 1
    On MacOS X (10.7.1), /bin/sh rejects the function name, but /bin/bash accepts it, dashes and all. Since regular commands can have dashes in the name, it makes sense for bash to allow them too; it is likely not mandated by the POSIX standard, though. Commented Sep 22, 2011 at 19:51

5 Answers 5

5

This line:

if [ ignored-deps-are-not-set ] 

tests whether the string 'ignored-deps-are-not-set' is empty or not. It returns true because the string is not empty. It does not execute a command (and hence the function).

If you want to test whether a variable is set, use one of the ${variable:xxxx} notations.

if [ ${ignored_deps+x} ] then echo "ignored_deps is set ($ignored_deps)" else echo "ignored_deps is not set" fi 

The ${ignored_deps+x} notation evaluates to x if $ignored_deps is set, even if it is set to an empty string. If you only want it set to a non-empty value, then use a colon too:

if [ ${ignored_deps:+x} ] then echo "ignored_deps is set ($ignored_deps)" else echo "ignored_deps is not set or is empty" fi 

If you want to execute the function (assuming the dashes work in the function name), then:

if ignored-deps-are-not-set then echo "Function returned a zero (success) status" else echo "Function returned a non-zero (failure) status" fi 
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, and No. Mainly, No. You'd write: if [ $(command to execute) ] or something similar, but the command is executed because of the $(...) and not because of the [ ... ]. I just recently fixed some shell script (at work) that contained: if ( $( [ -z "$variable" ] ) ) then notations (except the $(...) part was just back-ticks, but they're hard to handle in Markdown comments). Can you see why that is so ghastly?
Wow, that is gross. Thanks for all the detail.
2

You're not actually executing the function:

if ignored-deps-are-not-set; then ... 

Withing [] brackets, the literal string "ignored-deps-are-not-set" is seen as true.

2 Comments

So can I not execute any commands inside the brackets at all? I thought that was the difference between single and double brackets.
brackets (single or double) are for conditional expressions. you can execute commands within (provided you use backticks or $() syntax) and then compare the result with something. if you just want to run a command and test the exit status, you don't need brackets.
0
if [ ${myvar:-notset} -eq "notset" ] then ... 

Comments

0

Yet another way to test for the existence of a variable:

if compgen -A variable test_existence_of_var; then echo yes else echo no fi 

1 Comment

Is compgen normally found on a typical Linux install?
0

--edit-- just realized that it's a function tha tyou're trying to call, convention is wrong.

See:

Z000DGQD@CND131D5W6 ~ $ function a-b-c() { > return 1 > } Z000DGQD@CND131D5W6 ~ $ a-b-c Z000DGQD@CND131D5W6 ~ $ echo $? 1 Z000DGQD@CND131D5W6 ~ $ if a-b-c; then echo hi; else echo ho; fi ho Z000DGQD@CND131D5W6 ~ $ if [ a-b-c ]; then echo hi; else echo ho; fi hi Z000DGQD@CND131D5W6 ~ 

--edit end--

Fix the variable name (see my comment to your post)

then

See Parameter Expansion section in man bash.

${parameter:?word}: 

Display Error if Null or Unset. If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.