1

I am trying to write a bash script that takes in an option. Lets call these options A and B.

In the script A and B may or may not be defined as variables.

I want to be able to check if the variable is defined or not.

I have tried the following but it doesn't work.

if [ ! -n $1 ]; then 
   echo "Error"
fi

Thanks

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
user821602
  • 31
  • 1
  • 4
  • Does this question help: http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options – Dave Jun 29 '11 at 17:16

4 Answers4

1

The "correct" way to test whether a variable is set is to use the + expansion option. You'll see this a lot in configure scripts:

if test -s "${foo+set}"

where ${foo+set} expands to "set" if it is set or "" if it's not. This allows for the variable to be set but empty, if you need it. ${foo:+set} additionally requires $foo to not be empty.

(That $(eval echo $a) thing has problems: it's slow, and it's vulnerable to code injection (!).)

Oh, and if you just want to throw an error if something required isn't set, you can just refer to the variable as ${foo:?} (leave off the : if set but empty is permissible), or for a custom error message ${foo:?Please specify a foo.}.

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • I like this, and [P.E.](http://mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion) is nice. Just wanted to mention here too, that bash v4+ (iirc) provides the `-v` test, as mentioned in my answer, to denote if a variable is set. – c00kiemon5ter Jun 29 '11 at 17:58
0

The trick is "$1", i.e.

root@root:~# cat auto.sh
Usage () {

        echo "error"
}
if [ ! -n $1 ];then
        Usage
        exit 1
fi
root@root:~# bash auto.sh
root@root:~# cat auto2.sh
Usage () {

        echo "error"
}
if [ ! -n "$1" ];then
        Usage
        exit 1
fi
root@root:~# bash auto2.sh
error
LinconFive
  • 1,718
  • 1
  • 19
  • 24
0

Don't do it that way, try this:

if [[ -z $1 ]]; then
    echo "Error"
fi

The error in your version is actually the lack of quoting.
Should be:

if [ ! -n "$1" ]; then
    echo "Error"
fi

But you don't need the negation, use -z instead.

If you work on Bash, then use double brackets [[ ]] too.

from the man bash page:

 -z string
      True if the length of string is zero.
 -n string
      True if the length of string is non-zero.

Also, if you use bash v4 or greater (bash --version) there's -v

 -v varname
      True if the shell variable varname is set (has been assigned a value).
c00kiemon5ter
  • 16,994
  • 7
  • 46
  • 48
0

You did not define how these options should be passed in, but I think:

if [ -z "$1" ]; then
   echo "Error"
   exit 1
fi

is what you are looking for.

However, if some of these options are, err, optional, then you might want something like:

#!/bin/bash
USAGE="$0: [-a] [--alpha] [-b type] [--beta file] [-g|--gamma] args..."

ARGS=`POSIXLY_CORRECT=1 getopt -n "$0" -s bash -o ab:g -l alpha,beta:,gamma -- "$@"`
if [ $? -ne 0 ]
 then
  echo "$USAGE" >&2
  exit 1
 fi
eval set -- "$ARGS"
unset ARGS

while true
 do
  case "$1" in
   -a) echo "Option a"; shift;;
   --alpha) echo "Option alpha"; shift;;
   -b) echo "Option b, arg '$2'"; shift 2;;
   --beta) echo "Option beta, arg '$2'"; shift 2;;
   -g|--gamma) echo "Option g or gamma"; shift;;
   --) shift ; break ;;
    *) echo "Internal error!" ; exit 1 ;;
  esac
 done

echo Remaining args
for arg in "$@"
 do
  echo '--> '"\`$arg'"
 done

exit 0
Seth Robertson
  • 30,608
  • 7
  • 64
  • 57