Home > Bash, Programming > Combine regular expression and conditional statements in BASH

Combine regular expression and conditional statements in BASH

As we all know we can use conditional statements in BASH. For example, show usage if number of arguments is 0:

#!/usr/bin/env bash
if [ $# -eq 0 ]; then
    echo "Usage: $0 start|stop|restart"
    exit 0
fi
echo "going to run with \$1=$1"

We might also want to use regular expression to test if $1 is start, stop or restart if $# is no longer 0:

#!/usr/bin/env bash
function usage() {
    echo "Usage: $0 start|stop|restart"
}
if [ $# -eq 0 ]; then
    usage
    exit 0
fi

if [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
    usage
    exit 0
fi
echo "going to run with \$1=$1"

But wouldn’t it be nice if the tests can be combined together. With bash operator || the above code can be written as:

#!/usr/bin/env bash
function usage() {
    echo "Usage: $0 start|stop|restart"
}   
if [ $# -eq 0 ] || [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
    usage
    exit 0
fi  
echo "going to run with \$1=$1"

One more example using operator && instead:

#!/usr/bin/env bash
if [ -d ~/a_folder ] && [[ $1 =~ ^(install|remove)$ ]]; then
    echo "going to $1 something" 
else
    echo "Folder ~/a_folder doesn't exist or you specified the wrong parameter:"
    echo "Usage: $0 install|remove" 
    exit 0
fi  
Advertisements
Categories: Bash, Programming
  1. E E
    January 1, 2012 at 2:04 pm

    Some thoughts

    1) using “#!/bin/bash” is nearly always wrong.
    You either want to say “Use the bash in the user’s PATH” which is “#!/usr/bin/env bash” or you mean to say “use the POSIX shell” which is #!/bin/sh.

    using a direct reference to #!/bin/bash or #!/usr/local/bin/bash only makes sense in operating system specific scripts (and even then it is likely wrong)
    2) if [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
    looks bad. I would use a case statement:

    case $1 in
    ‘start’ | ‘stop’ | ‘restart’)
    dosomething;;
    esac

    3) function usage() …
    get rid of the word ‘function’ here – it isn’t portable.

    4) Please don’t use BASH for scripting. Use only POSIX features when writing scripts that others are intended to run. Using BASH for an interactive shell is fine on the other hand.

    • ricoch3n
      January 1, 2012 at 3:22 pm

      Having written many bash scripts mostly for either Linux and Mac OS X, I rarely thought about portability issues. You truly have raised some very good points here. I have made some modifications based on your comments (with two exceptions, see below). Thanks for pointing them out.

      2) if [[ ! $1 =~ ^(start|stop|restart)$ ]]; thenlooks bad. I would use a case statement:case $1 in’start’ | ‘stop’ | ‘restart’) dosomething;;esac

      I have to agree that the case statement is a better approach for this simple example, and not all versions of BASH support regular expression but the purpose of this post is to demo how to combine conditional statements with RE.

      4) Please don’t use BASH for scripting. Use only POSIX features when writing scr are intended to run. Using BASH for an interactive shell is fine on the other hand.er hand.

      I found it’s quite convenient to write BASH scripts for simple stuff or even something a bit complicated, scripting with tmux, for example.

      Thanks again for your invaluable input. Happy New Year!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: