224

Sometimes when making conditionals, I need the code to do nothing, e.g., here, I want Bash to do nothing when $a is greater than "10", print "1" if $a is less than "5", otherwise, print "2":

if [ "$a" -ge 10 ]
then
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

This makes an error though. Is there a command which will do nothing and also not slow down my script?

codeforester
  • 28,846
  • 11
  • 78
  • 104
Village
  • 18,301
  • 39
  • 106
  • 153

3 Answers3

401

The no-op command in shell is : (colon).

if [ "$a" -ge 10 ]
then
    :
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

From the bash manual:

: (a colon)
Do nothing beyond expanding arguments and performing redirections. The return status is zero.

Barmar
  • 596,455
  • 48
  • 393
  • 495
  • 4
    @SaintHax No, it doesn't run `true`. It's built into the shell, and does nothing. – Barmar May 26 '17 at 19:29
  • 1
    it is shell built in (you are correct), it returns true (status 0) just like true does, and it is more difficult to read. Bash is a DevOps language, and if `:` is written by someone on my team, I'd have them change it. – SaintHax May 29 '17 at 19:51
  • 3
    @SaintHax If someone used `true` in a non-conditional context, I'd have them change it. `if true` is fine, `then true` seems wrong. – Barmar May 29 '17 at 21:29
  • 1
    Of course, you can simply rewrite the code to use `if ! condition; then do something; fi` instead of `if condition; then :; else do something; fi`. – Barmar May 29 '17 at 21:30
  • I agree with you. This example could be written if/elif/else using compound conditions and would be better. – SaintHax May 30 '17 at 13:50
50

You can probably just use the true command:

if [ "$a" -ge 10 ]; then
    true
elif [ "$a" -le 5 ]; then
    echo "1"
else
    echo "2"
fi

An alternative, in your example case (but not necessarily everywhere) is to re-order your if/else:

if [ "$a" -le 5 ]; then
    echo "1"
elif [ "$a" -lt 10 ]; then
    echo "2"
fi
Flimzy
  • 60,850
  • 13
  • 104
  • 147
  • 8
    If you don't test the result both `true` and `false` are effectively no-ops as far as the script is concerned, but in principle they *could* fork in some shells that accept this syntax so perhaps `:` is better. – dmckee --- ex-moderator kitten Jul 11 '13 at 01:31
  • 3
    The question is tagged bash. In bash, `true` and `false` are built-ins. For older shells, `true`, `false`, and even `:` might be external commands (though you'd probably see the latter only in *very* old shells). – Keith Thompson Jan 12 '14 at 04:37
  • 7
    I prefer `:` simply because it is more explicit what the intent is – Freedom_Ben Sep 19 '14 at 21:12
10

Although I'm not answering the original question concering the no-op command, many (if not most) problems when one may think "in this branch I have to do nothing" can be bypassed by simply restructuring the logic so that this branch won't occur.

I try to give a general rule by using the OPs example

do nothing when $a is greater than "10", print "1" if $a is less than "5", otherwise, print "2"

we have to avoid a branch where $a gets more than 10, so $a < 10 as a general condition can be applied to every other, following condition.

In general terms, when you say do nothing when X, then rephrase it as avoid a branch where X. Usually you can make the avoidance happen by simply negating X and applying it to all other conditions.

So the OPs example with the rule applied may be restructured as:

if [ "$a" -lt 10 ] && [ "$a" -le 5 ]
then
    echo "1"
elif [ "$a" -lt 10 ]
then
    echo "2"
fi

Just a variation of the above, enclosing everything in the $a < 10 condition:

if [ "$a" -lt 10 ]
then
    if [ "$a" -le 5 ]
    then
        echo "1"
    else
        echo "2"
    fi
fi

(For this specific example @Flimzys restructuring is certainly better, but I wanted to give a general rule for all the people searching how to do nothing.)

Community
  • 1
  • 1
KeyNone
  • 7,527
  • 4
  • 32
  • 49
  • 5
    One reason someone might want to have a no-op is when initially structuring the code with the idea that one will add the "add something here later" without having inadvertent side effects. E.g. if one is putting an if-then-else-fi in a .bashrc, if you put `echo "put stuff here"` it'll break some of the non-login uses (e.g. scp gets broken), and only whitespace/comments causes a runtime error. – Aphoid Jan 02 '18 at 16:38
  • Also, personally, I prefer to write code that is more "human friendly". It's often possible to restructure code to be more concise or even efficient. But when that's not critical, I prefer my code to be more readable for whichever developer comes along afterwards. (I also like commenting my code.) – osullic Jan 06 '21 at 10:08