Differences between revisions 14 and 15
Revision 14 as of 2011-03-06 13:00:30
Size: 2465
Editor: adsl-75-61-98-203
Comment: Typo: example and comment text should use same variable name.
Revision 15 as of 2012-07-28 15:38:39
Size: 2673
Editor: cpc1-aztw4-0-0-cust1957
Comment: Documented converse: -z instead of -n, otherwise added !.
Deletions are marked like this. Additions are marked like this.
Line 13: Line 13:
}}}

To check the converse, whether a variable is empty (unset or zero-length), you can use:

{{{
test x"$var" = x
test -z "$var"
[ -z "$var" ]
test ! "$var"
[ "$var" ]
[[ -z $var ]]
[[ ! $var ]]

How do I determine whether a variable is already defined? Or a function?

There are several ways to determine whether a variable is defined to have a non-empty value. Here are the most common ones, in order from most portable to least portable:

test x"$var" != x
test -n "$var"
[ -n "$var" ]
test "$var"
[ "$var" ]
[[ -n $var ]]
[[ $var ]]

To check the converse, whether a variable is empty (unset or zero-length), you can use:

test x"$var" = x
test -z "$var"
[ -z "$var" ]
test ! "$var"
[ "$var" ]
[[ -z $var ]]
[[ ! $var ]]

If you need to distinguish between a variable that is undefined and one that is defined but empty, then it becomes much trickier. There is no explicit shell command to test for existence of a variable (until bash 4.2), but there are some tricks that can be used. With older bash releases, one way is to use "declare":

# Bash
declare -p var >/dev/null 2>&1
# returns 0 if var exists, error otherwise

Here's another one that uses parameter expansion:

# Bourne
test "${var+defined}"

This expansion results in nothing if var is undefined. Therefore test returns false. If var is defined (to either "" or something longer), the expansion returns "defined", and therefore test returns true. You could use any non-empty string in place of "defined", but readability is always nice.

Bash 4.2 adds a -v test:

# Bash 4.2
if [[ -v var ]]; then echo "var is defined"; fi

Another way is to use a SubShell which will exit with an error code if an unbound variable is used:

# bash/ksh work ... others?
if (set -u; : $UNBOUND_VAR) 2>/dev/null ; then
  echo "the variable has been set"
else
  echo "the variable has not been set"
fi

(This is much slower and uglier than simply using the ${var+defined} expansion.)

For determining whether a function with a given name is already defined, there are several answers, all of which require Bash (or at least, non-Bourne) commands:

# Bash
# These two are best:
if [[ $(declare -f foo) ]]     # it prints nothing, if undefined
if declare -f foo >/dev/null   # it also sets the exit status

# These are a little more obvious, but...
if [[ $(type foo 2>&1) = *' is a function'* ]]
if type foo >/dev/null 2>&1 && ! type -f foo >/dev/null 2>&1

A related question is, Why on earth does anyone want this? Why not just define the function already?

I don't know. I think it has something to do with reflection. But people keep asking it, so....

BashFAQ/083 (last edited 2022-11-26 06:06:57 by emanuele6)