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

1

4 Answers 4

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.}.

Sign up to request clarification or add additional context in comments.

1 Comment

I like this, and P.E. 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.
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

Comments

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).

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.