简体   繁体   中英

Detect number of argument and the value passed into the bash

I want to make sure my bash script can correctly detect user's input argument. Specifically, user can only pass 1 or 2 or 3 into the script, otherwise the script will be terminated. I wrote the following code:

#!/bin/bash

for args in $@
do
    echo $args
done

if [ "$#" != 1 ] && [ "$#" -ne 1 ]; then
        echo "Illegal number of parameters"
        exit 1
fi

This script can only capture when user does not give any input, but cannot check whether user indeed input the number 1 not other values.

By the way, I am not sure how to express "input argument can accept number 1 or 2 or 3".

$# is an integer, so you have to use integer comparison. You can for example say:

if [ "$#" -ne 1 ]; then
   echo "illegal number of parameters"
   exit 1
fi

To check that the parameter is either 1, 2 or 3, you can use this regular expression (see something related ):

if [[ ! $1 =~ ^(1|2|3)$ ]]; then
    echo "the number is not 1, 2 or 3"
    exit 1
fi

To express "input argument can accept number 1 or 2 or 3" I would for example say "we can just accept the argument being either 1, 2 or 3".

First off you can detect if the string is null or empty simply by doing the following:

if [ -z "$1" ]
  then
  echo "Argument $1 contains nothing"
fi

That I would say is your first step, and will allow you to filter out args that have no content.

Following on from that, you'd most likely need to do some comparison work on $1, $2 & $3

I'll just check something and come back to this in a moment.

Update

Just had to go find one of my scripts and check something... :-)

One way I've handled the checking of parms in the past is something like the following

#!/bin/sh
while [ $# -gt 0 ] || [ "$#" -le 4 ]; do
  case "$1" in
    *[!1-9]*)   echo "Text: $1";;
    *)          echo "Number: $1"
  esac

  case "$2" in
    *[!1-9]*)   echo "Text: $2";;
    *)          echo "Number: $2"
  esac

  case "$3" in
    *[!1-9]*)   echo "Text: $3";;
    *)          echo "Number: $3"
  esac

  shift
done

Basically a simple regex, if I have more than 0 parameters or less than 4 parameters then I allow it through to a case statement, which then checks the content of each parameter.

This one just has an echo in, but you could just as easy set some flags, and then decide how to continue based on those flags.

For simple range checking however, you might just want to use a one liner similar to the following:

if [[ $# -gt 0 && $# -lt 4 ]]; then echo "Correct number of parameters"; fi

Again setting a flag to use later rather than echoing the results.

I assume you mean the input can only be 1, 2 or 3, so using a case statement is the best way. $1 is the variable that stores your argument, if it is equal to 1 case will execute the code in the block corresponding to the value 1 and so on.

 case "$1" in
        1) ...
        ;;
        2) ...
        ;;
        3) ...
        ;;
        *) echo "Invalid argument"
        ;;
     esac

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM