shell booleans are commands!

2014-10-03

How should we represent boolean flags in shell? A common approach, possibly inspired by C, is to set the variable to either 0 or 1.

Then you see code like this:


if [ $debug = 1 ]; then
...

or this example from zgrep:


if test $have_pat -eq 0; then
...

there is nothing special about 0 and 1, they are just two strings for repreresenting “the flag is set” and “the flag is unset”.

Test for strings is surprisingly awkward in shell. In Python you can go if debug: .... It would be nice if we could do something similar in shell:


if $debug ; then
...
fi

Well we can. In a shell if statement, if thing, the thing is just a command. If we arrange that debug is either true or false, then if $debug will run either the command true or the command false.


debug=true # sets flag
debug=false # unsets flag

I wish I could remember who I learnt this trick off because I think it’s super cool, and not enough shell programmers know about it. true and false are pretty much self explanatory as boolean values, and no extra code is needed because they already exist as shell commands.

You can also use this with &&:


$debug && stuff

Sometimes shell scripts have a convention where a variable is either unset (to mean false) or set to anything (to mean true). You can convert from this convention to the true/false convention with 2 lines of code:


# if foo is set to anything, set it to "true"
foo=${foo+true}
# if foo is the empty string, set it to "false"
foo=${foo:-false}

One Response to “shell booleans are commands!”

  1. Tony Finch Says:

    I use this idiom too, but it is slightly troublesome: the result of evaluating a Boolean command is not the same kind of Boolean that you started with. So you have to write the longwinded

    if $a && $b; then c=true; else c=false; fi

    rather than the more direct

    c=$($a && $b) # wrong


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: