runegjo
runegjo

Reputation: 31

Validate bash script arguments

I am trying to do something like this to make a script to perform backups if they have failed. I am taking in the environment as argument to the script.

The one thing i am unsure on how to do is that i want to verify $1 to only include some predefined values. The predefined values should be something like tst, prd, qa, rpt. Anyone?

#!/bin/bash
ENVIRONMENT=$1 
BACKUPDATE=$(date +"%d_%m_%Y")
BACKUPFILE="$ENVIRONMENT".backup."$BACKUPDATE".tar.gz

if [ $1 ==  "" ] 
 then
 echo "No environment specified"
 exit
elif [ -f "$BACKUPFILE" ]; then
   echo "The file '$BACKUPFILE' exists."
else
   echo "The file '$BACKUPFILE' in not found."
   exec touch "$BACKUPFILE"
fi

Upvotes: 3

Views: 394

Answers (2)

Matthieu
Matthieu

Reputation: 3098

You can use case:

case "$1" in
    tst) echo "Backing up Test style" ;;
    prd)
        echo "Production backup"
        /etc/init.d/myservice stop
        tar czf ...
        /etc/init.d/myservice start
        ;;
    qa) echo "Quality skipped" ;;
    rpt)
        echo "Different type of backup"
        echo "This could be another processing"
        ...
        ;;
    *)
        echo "Unknown backup type"
        exit 2
        ;;
esac

Note the double ;; to end each case, and the convenient use of pattern matching.

Edit: following your comment and @CharlesDuffy suggestion, if you want to have all valid options in an array and test your value against any of them (hence having the same piece of code for all valid values), you can use an associative array:

declare -A valids=(["tst"]=1 ["prd"]=1 ["qa"]=1 ["rpt"]=1)
if [[ -z ${valids[$1]} ]] ; then
    echo "Invalid parameter value"
    # Any other processing here ...
    exit 1
fi
# Here your parameter is valid, proceed with processing ...

This works by having a value (here 1 but it could be anything else in that case) assigned to every valid parameter. So any invalid parameter will be null and the -z test will trigger.

Credits go to him.

Upvotes: 3

Jens
Jens

Reputation: 72629

Depending on how many different values you have, what about a case statement? It even allows for globbing.

case $1 in
  (John)   printf "Likes Yoko\n";;
  (Paul)   printf "Likes to write songs\n";;
  (George) printf "Harrison\n";;
  (Ringo)  printf "Da drumma\n";;
  (*)      printf "Management, perhaps?\n";;
esac

On another note, if you can you should avoid unportable bashisms like the [[ test operator (and use [ if you can, e.g. if [ "$1" = "John" ]; then ...; fi.)

Upvotes: 1

Related Questions