Home > Bash, Programming, Tip > Replace if … then … fi with && and || in Bash

Replace if … then … fi with && and || in Bash

&& and || are the shorthand of if … then … fi in Bash. They
are very useful in writing simple scripts, for example:

1. Run script based on day of week:

[ $(date +%w) -eq 6 ] && echo "do something on Saturdays" || echo "do different things on other days"

The equivalent if block of the above would be:

if [ $(date +%w) -eq 6 ]; then
    echo "do something on Saturdays"
else
    echo "do different things on other days"
fi

If more commands are needed when if condition matches (or doesn’t match), you can use { } to put the commands together

[ $(date +%w) -eq 6 ] && {echo "do something on Saturdays"; do_some_other_stuff; exit 0;} || echo "do different things on other days"

The shorthand also makes it easier to write stuffs to crontab, for example, we can put the something like this to crontab

1 8 * * * [ $(date +\%d) -eq 1 ] && ~/scripts/run_stuff_on_first_day_of_a_month

The ‘%’ is escaped, you can check out my another post regarding this.

2. Make sure a specific mount exists
Sometimes we need to make sure a mount point exists before any other tasks can be performed, it’s quite simple to do it with the shorthand form of conditional block:

mount|grep -q "^/dev/sdb1 " || mount /mnt/datastore

This will ensure partition /dev/sdb1 will be mounted to /mnt/datastore. A couple of things are worth pointing out:
1) grep option -q will suppress std output from grep, results are stored in $?, from which operator || will determine to run “mount /mnt/datastore” or not.
2) ^/dev/sdb1 instead of /mnt/datastore is used for the regular expression to eliminate false match. It’s unlikely but possible that the following mount point might exists
/dev/somepartition on /mnt/datastore 2 (ext3, local …)
An additional space is inserted to the end of the regexp in case there are partitions such as /dev/sdb1X (x=0-9) mounted.

3. Make sure a specific folder exists, if not, create it before script runs. For example:

[ -d /tmp/mydir/work ] || mkdir -p /tmp/mydir/work
Advertisements
Categories: Bash, Programming, Tip
  1. Eric
    October 19, 2011 at 6:13 am

    same for javascript.

    • ricoch3n
      October 19, 2011 at 7:49 am

      Indeed and I use the same technique quite often in js codes.
      for example,

      var a=3;
      var b;
      (a==3) && (b=5); // the parentheses surrounding b=5 are necessary, code becomes invalid if they are missing
      console.log(b);

      //
      $(‘someselector’).hasClass(‘current’) && do_something();

  2. June 16, 2014 at 11:45 am

    I love using the && || shorthands but they does not always do the same thing as the full if statement. Consider this:

    if cmd1 ; then
    cmd2
    else
    echo fail
    fi

    Will print “fail” only if cmd1 fails.

    cmd1 && cmd2 || echo fail

    Will print “fail” if cmd1 OR cmd2 fails.

    If you want to surpress the echo then you can write:

    cmd1 &|| echo fail

    But if you rely on the status code of cmd2 to propagate then you need to use a full if statement (as far as I know):

    if cmd1 ; then cmd2 ; else echo fail ; fi

  3. kakalaket@gmx.net
    November 24, 2016 at 8:38 am

    Hi,
    this is an old post, but there seems to be a Bug or a issue you have to know about this syntax !

    If you run into the first if condition, and the last command returns a non zero return-value, ksh and bash run ALSO in the second one.

    Example:
    [ $(date +%w) -eq 4 ] && (echo “do something today”;test -f x)|| echo “do different things on other days”
    do something today
    do different things on other days

    How to get around this issue ?
    The short syntax seems to not following the rule if [condition] then [command] else [else_command]

    Instead it runs like:
    if [condition] then do [something] if [command] fail, then do [else_command] as well.

    Cu
    k.

  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: