0

So, I'm setting up a bash script and want to parse arguments to certain flags using getopts. For a minimal example, consider the a script which has a flag, -M, and it takes y or n as an argument. If I use the following code:

#!/bin/bash

# minimalExample.sh

while getopts "M:" OPTION;
do
case ${OPTION} in
        M)  
            RMPI=${OPTARG}
            if ! [[ "$RMPI" =~ "^[yn]$" ]]
            then
                echo "-M must be followed by either y or n."
                exit 1
            fi
            ;;
esac
done

I get the following:

$ ./minimalExample.sh -M y
-M must be followed by either y or n.
FAIL: 1

However, if I use the following code instead

#!/bin/bash

# minimalExample2.sh

while getopts "M:" OPTION;
do
case ${OPTION} in
        M)  
            RMPI=${OPTARG}
            if [ -z $(echo $RMPI | grep -E "^[yn]$") ]
            then
                echo "-M must be followed by either y or n."
                exit 1
                            else
                                    echo "good"
            fi
            ;;
esac
done

I get:

$ ./minimalExample2.sh -M y
good

Why doesn't minimalExample.sh work?

StevieP
  • 1,569
  • 12
  • 23

2 Answers2

2

quoting regexp in this context forces a string comparison.

change to

if ! [[ "$RMPI" =~ ^[yn]$ ]]

check following post for more details,

bash regex with quotes?

Community
  • 1
  • 1
dpp
  • 1,748
  • 11
  • 7
0

Why do you need regex here at all? -M y is not the same as -M n, is it? So you definitely will use some statement (case or if) to distinguish one from another.

#!/bin/bash

while getopts "M:" OPTION; do
    case ${OPTION} in
            M)  
                case ${OPTARG} in
                    y) 
                        # do what must be done if -M y
                        ;;
                    n) 
                        # do what must be done if -M n 
                        ;;
                    *) 
                        echo >&2 "-M must be followed by either y or n."
                        exit 1
                        ;;
                ;;
    esac
done

Please note >&2 – error messages should be output to STDERR, not to STDOUT.

Dmitry Alexandrov
  • 1,693
  • 12
  • 14
  • Perhaps because at this point in the code, he is only validating the value of `RMPI`, and the specific value of `y` or `n` is not used until later. – chepner Jan 09 '14 at 22:34
  • @chepner is entirely correct. The case control in the beginning of my script is more for argument validation than anything else. – StevieP Jan 10 '14 at 00:21