Bash. Test for unset variable using function

A simple test of the Bash variable:

${varName:? "${varName} is not defined"} 

I would like to reuse this by putting it in a function. How to like it?

Failed to complete

 # # Test a variable exists tvar(){ val=${1:? "${1} must be defined, preferably in $basedir"} if [ -z ${val} ] then echo Zero length value else echo ${1} exists, value ${1} fi } 

those. I need to exit if the test fails.

+28
variables bash undefined
May 17 '09 at 11:18
source share
7 answers

Thanks to lhunath's answer, I got to the Bash man page, which I skipped hundreds of times:

     When not performing substring expansion, bash tests for a parameter that
     is unset or null;  omitting the colon results in a test only for a parameโ€
     ter that is unset.

This prompted me to create the following truth table:

                 |  unset |  set |  set and |  meaning
                 |  |  but null |  not null |
     ============= + ======== + ========== + ========== + ======= ========================
      $ {var-_} |  T |  F |  T |  not null or not set
     ------------ + ------- + ---------- + ---------- + ------- ----------------------
      $ {var: -_} |  T |  T |  T |  always true, use for subst.
     ------------ + ------- + ---------- + ---------- + ------- ----------------------
      $ var |  F |  F |  T |  var is set and not null
     ------------ + ------- + ---------- + ---------- + ------- ----------------------
      $ {! var [@]} |  F |  T |  T |  var is set

This table shows the specification on the last line. The Bash man page says: โ€œIf the name is not an array, it expands to 0, if the name is specified, and otherwise isโ€œ null. โ€For the purposes of this truth table, it behaves the same, even if it is an array.

+46
Sep 24 '09 at 2:04
source share

What you are looking for is indirect.

 assertNotEmpty() { : "${!1:? "$1 is empty, aborting."}" } 

This causes the script to abort with an error message if you execute something like this:

 $ foo="" $ assertNotEmpty foo bash: !1: foo is empty, aborting. 

If you just want to check if foo empty, instead of interrupting the script, use this instead of the function:

 [[ $foo ]] 

For example:

 until read -p "What is your name? " name && [[ $name ]]; do echo "You didn't enter your name. Please, try again." >&2 done 

Also note that there is a very important difference between the empty and unset parameters. You must take care not to confuse these conditions! An empty parameter is one that is installed, but simply set to an empty string. The unset parameter is one that does not exist at all.

In the previous examples, everything is checked for empty parameters. If you want to check the unset parameters and read all the given parameters OK, whether they are empty or not, use this:

 [[ ! $foo && ${foo-_} ]] 

Use it in a function like this:

 assertIsSet() { [[ ! ${!1} && ${!1-_} ]] && { echo "$1 is not set, aborting." >&2 exit 1 } } 

Which will only abort the script when the name of the parameter you pass indicates a parameter that is not set:

 $ ( foo="blah"; assertIsSet foo; echo "Still running." ) Still running. $ ( foo=""; assertIsSet foo; echo "Still running." ) Still running. $ ( unset foo; assertIsSet foo; echo "Still running." ) foo is not set, aborting. 
+18
May 17 '09 at 12:36
source share

You want to use [ -z ${parameter+word} ]

Some part of man bash :

 Parameter Expansion ... In each of the cases below, word is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. When not performing substring expansion, bash tests for a parameter that is unset or null; omitting the colon results in a test only for a parameter that is unset. ... ${parameter:+word} Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted. ... 

In other words:

  ${parameter+word} Use Alternate Value. If parameter is unset, nothing is substituted, otherwise the expansion of word is substituted. 

a few examples:

 $ set | grep FOOBAR $ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi it is unset $ declare FOOBAR $ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi $ FOOBAR= $ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi $ FOOBAR=1 $ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi $ unset FOOBAR $ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi it is unset $ 
+5
Nov 26 '12 at 19:35
source share

This function checks the variables that ARE CURRENTLY are set. A variable can even be an array. Note that in bash: 0 == TRUE, 1 == FALSE.

 function var.defined { eval '[[ ${!'$1'[@]} ]]' } # Typical Usage of var.defined {} declare you="Your Name Here" ref='you'; read -p "What your name: " you; if var.defined you; then # Simple demo using literal text echo "BASH recognizes $you"; echo "BASH also knows a reference to $ref as ${!ref}, by indirection."; fi unset you # have just been killed by a master :D if ! var.defined $ref; then # Standard demo using an expanded literal value echo "BASH doesn't know $ref any longer"; fi read -s -N 1 -p "Press any key to continue..."; echo ""; 

So, to be clear here, the function checks the literal. Each time a command is invoked in bash, the GENERALLY variables are "reset" or "replaced" with the base value, unless:

  • $ varRef ($): \ $ varRef
  • $ varRef - single quote '$ varRef'
+3
May 15 '11 at 2:09
source share

I definitely did not understand what you need. I try to answer you despite this.

those. I need to exit if the test fails.

The code:

 ${varName:? "${varName} is not defined"} 

will return a nonzero exit code if there is no variable named "varName". The last command completion code is stored in $? .

About your code:

 val=${1:? "${1} must be defined, preferably in $basedir"} 

Perhaps he is not doing what you need. In case $1 not defined, "${1}" will not be replaced by anything. You probably want to use single quotes that literally write ${1} without wildcard.

 val=${1:? '${1} must be defined, preferably in $basedir' 
+1
May 17 '09 at 12:02
source share

Not sure if this is exactly what you want, but the convenient trick I use when writing a new + complex script is to use "set -o"

set -o # will do the bomb script when it finds an unset variable

EG:

$ grep '$ 1' chex.sh

case "$ 1" in

$. / chex.sh

./chex.sh: line 111: $ 1: unbound variable

$. / chex.sh foo

wrong / no parameters passed. Exit from

+1
Nov 06 2018-10-10T00:
source share
 if set | grep -q '^VARIABLE=' then echo VARIABLE is set fi 
+1
Jun 01 '14 at 7:40
source share



All Articles