[bash] Check existence of input argument in a Bash shell script

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?

This question is related to bash shell

The answer is


Try:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi

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.


Only because there's a more base point to point out I'll add that you can simply test your string is null:

if [ "$1" ]; then
  echo yes
else
  echo no
fi

Likewise if you're expecting arg count just test your last:

if [ "$3" ]; then
  echo has args correct or not
else
  echo fixme
fi

and so on with any arg or var


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.

In my case the only working solution to check if last arguments exists is:

if [[ "$7" == '' ]] ; then
  echo "error"
  exit
fi

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.


I often use this snippet for simple scripts:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi

one liner bash function validation

myFunction() {

    : ${1?"forgot to supply an argument"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

add function name and usage

myFunction() {

    : ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

add validation to check if integer

to add additional validation, for example to check to see if the argument passed is an integer, modify the validation one liner to call a validation function:

: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"

then, construct a validation function that validates the argument, returning 0 on success, 1 on failure and a die function that aborts script on failure

validateIntegers() {

    if ! [[ "$1" =~ ^[0-9]+$ ]]; then
        return 1 # failure
    fi
    return 0 #success

}

die() { echo "$*" 1>&2 ; exit 1; }

Even simpler - just use set -u

set -u makes sure that every referenced variable is set when its used, so just set it and forget it

myFunction() {
    set -u
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

If you'd like to check if the argument exists, you can check if the # of arguments is greater than or equal to your target argument number.

The following script demonstrates how this works

test.sh

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi

produces the following output

$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments

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.