Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I need to check the existence of an input argument. I have the following script:

if [ "$1" -gt "-1" ]
  then echo hi
fi

I get

[: : integer expression expected

How do I check the input argument1 first to see if it exists?

share|improve this question
up vote 882 down vote accepted

It is:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi

The $# variable will tell you the number of input arguments the script was passed.

Or you can check if an argument is an empty string or not like:

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi

The -z switch will test if the expansion of "$1" is a null string or not. If it is a null string then the body is executed.

share|improve this answer
21  
I like to do it this way, in terse syntax and still POSIX acceptable. [ -z "$1" ] && echo "No argument supplied" I prefer one-liners, as they are easier for me; and it's also faster to check exit value, compared to using if – TechZilla Jun 2 '12 at 20:38
73  
You probably want to add an exit 1 at the end of your echos inside the if block when the argument is required for the script to function. Obvious, but worth noting for completeness. – msanford Feb 5 '13 at 16:37
8  
It is possible, though rarely useful, for the first argument to be initialized but empty; programname "" secondarg third. The $# check unambiguously checks the number of arguments. – tripleee May 6 '13 at 4:40
5  
For a noob, especially someone who comes from a non-scripting background, it is also important to mention some peculiarities about these things. You could have also mentioned that we need a space after the opening and the closing brace. Otherwise things do not work. I am myself a scripting noob (I come from C background) and found it the hard way. It was only when I decided to copy the entire thing "as is" that things worked for me. It was then I realized I had to leave a space after the opening brace and before the closing one. – HighOnMeat Sep 13 '13 at 7:17
26  
and for optional args if [ ! -z "$1" ]; then ... – gcb Feb 26 '14 at 23:18

It is better to demonstrate this way

if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 1
fi

You normally need to exit if you have too few arguments.

share|improve this answer
3  
This is the duplicate of the accepted answer, so I believe it should be removed. – kenorb Sep 10 '15 at 22:50
12  
No it isn't: this has exit 1 which you usually want, and uses the [[ ]] test which (iirc) is usually more reasonable. So for people blindly copy-pasting code this is the better answer. – dshepherd Nov 26 '15 at 11:22
3  
To know more about the difference between [ ] and [[ ]] see stackoverflow.com/questions/3427872/… – Sebastián Grignoli Feb 3 at 19:31
    
I think the pointer to [[ ]] and the exit 1 are helpful. – Steven Chanin Aug 30 at 16:44

If you're only interested in detecting if a particular argument is missing, parameter substitution is great:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

In some cases you need to check whether the user passed an argument to the script and if not, fall back to a default value. Like in the script below:

scale=${2:-1}
emulator @$1 -scale $scale

Here if the user hasn't passed scale as a 2nd parameter, I launch Android emulator with -scale 1 by default. ${varname:-word} is an expansion operator. There are other expansion operators as well:

  • ${varname:=word} which sets the undefined varname instead of returning the word value;
  • ${varname:?message} which either returns varname if it's defined and is not null or prints the message and aborts the script (like the first example);
  • ${varname:+word} which returns word only if varname is defined and is not null; returns null otherwise.
share|improve this answer

Another way to detect if arguments were passed to the script:

((!$#)) && echo No arguments supplied!

Note that (( expr )) causes the expression to be evaluated as per rules of Shell Arithmetic.

In order to exit in the absence of any arguments, one can say:

((!$#)) && echo No arguments supplied! && exit 1

Another (analogous) way to say the above would be:

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!

help let says:

let: let arg [arg ...]

  Evaluate arithmetic expressions.

  ...

  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
share|improve this answer

Try:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi
share|improve this answer
1  
Why do you need double-quotes for $# and 0? – user13107 Dec 12 '14 at 3:00
1  
No problem if we use without double-quotes as like $# and 0 – Ranjithkumar T Dec 15 '14 at 7:15
    
on windows, mingw this is the only way to go. – Mészáros Lajos Jun 11 '15 at 14:56
1  
This answer provides great starting point for a script I just made. Thanks for showing the else, too. – Chris K Jul 30 '15 at 22:46
1  
@user13107 double quoted variables in bash prevent globbing (i.e. expanding filenames like foo*) and word splitting (i.e. splitting the contents if the value contains whitespace). In this case it's not necessary to quote $# because both of those cases do not apply. Quoting the 0 is also not necessary, but some people prefer to quote values since they are really strings and that makes it more explicit. – Dennis Jan 31 at 20:21

As a small reminder, the numeric test operators in Bash only work on integers (-eq, -lt, -ge, etc.)

I like to ensure my $vars are ints by

var=$(( var + 0 ))

before I test them, just to defend against the "[: integer arg required" error.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.