1418

I tried to declare a Boolean variable in a shell script using the following syntax:

variable=$false

variable=$true

Is this correct? Also, if I wanted to update that variable would I use the same syntax? Finally, is the following syntax for using Boolean variables as expressions correct?

if [ $variable ]

if [ !$variable ]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hassaanm
  • 14,539
  • 4
  • 21
  • 20

27 Answers27

1693

Revised Answer (Feb 12, 2014)

the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
    echo 'Be careful not to fall off!'
fi

Original Answer

Caveats: https://stackoverflow.com/a/21210966/89391

the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
    echo 'Be careful not to fall off!'
fi

From: Using boolean variables in Bash

The reason the original answer is included here is because the comments before the revision on Feb 12, 2014 pertain only to the original answer, and many of the comments are wrong when associated with the revised answer. For example, Dennis Williamson's comment about bash builtin true on Jun 2, 2010 only applies to the original answer, not the revised.

Gurpartap Singh
  • 2,744
  • 1
  • 26
  • 30
miku
  • 181,842
  • 47
  • 306
  • 310
  • 47
    To explain what is happening: the `if` statement is executing the contents of the variable which is the Bash builtin `true`. Any command could be set as the value of the variable and its exit value would be evaluated. – Dennis Williamson Jun 02 '10 at 04:16
  • 7
    @pms The operators "-o" and "-a" are only for the "test" command (aka "[]"). Instead, this is "if + command", without the "test". (Like "if grep foo file; then ...".) So, use the normal `&&` and `||` operators: `# t1=true; t2=true; f1=false;` # `if $t1 || $f1; then echo is_true ; else echo is_false; fi;` _(returns "true", since t1=true)_ # `if $t1 && $f1 || $t2; then echo is_true ; else echo is_false; fi` _(returns "true", since t2=true)_ . Again, this ONLY works because "true"/"false" are bash-builtins (returning true/false). You can't use "if $var..." unless var is a cmd (ie, true or false) – michael Jun 30 '12 at 09:07
  • 20
    -1, [see my answer](http://stackoverflow.com/a/21210966/72321) for an explanation. – Dennis Jan 18 '14 at 23:04
  • 3
    Lots of incorrect information, here. /bin/true isn't being used effectively. See Dennis' answer. – ajk Feb 20 '14 at 01:09
  • 1
    This code is not the same and does not work in the same way as the linked article. The linked code calls a program by the name stored in a variable but the code in this answer is just string comparison. – Quolonel Questions Apr 01 '15 at 09:58
  • 1
    @ajk The reason that a lot of the comments seem incorrect is because miku's original answer was revised by another user on Feb 12, 2014, so it invalidated most of the previous comments. – wisbucky Jun 08 '15 at 23:02
  • The original answer was just better and completely safe as long as the assignments of the variable are completely controlled inside your script. – dolmen Mar 04 '16 at 13:41
  • VAR=true; $VAR && echo "TRUE" || echo "FALSE"; Show True and VAR=false; $VAR && echo "TRUE" || echo "FALSE"; Show False. So this is working properly... – Loenix Dec 13 '16 at 09:17
  • 1
    I think this answer can kill the kitties because the `true` in `the_world_is_flat` assignment is a command in the original answer! Let's check with `the_world_is_flat=date`... – andras.tim Sep 13 '17 at 12:29
  • 1
    DO NOT USE THE ORIGINAL ANSWER! It is executing a command every time you check the value and it's easy to forget how it works and put square brackets around it (which breaks it all). Short answer is: bash does not have booleans. It only has builtin testing (`[ ]`, `[[ ]]`, `test`) which evaluates to a boolean'ish exit code. You cannot define that boolean, though. – Hubert Grzeskowiak Nov 03 '17 at 09:11
  • 1
    About the newer answer: it is simple string comparison. When in bash, you should rather use double square brackets and quote everything so people know it's strings and nothing special. – Hubert Grzeskowiak Nov 03 '17 at 09:12
  • @HubertGrzeskowiak "It is executing a command every time you check the value": this is only true for _very_ old shells. true (and false) are built-in commands in bash (and virtually every other shell): no new process is started. – Levi Nov 30 '17 at 01:15
  • [[ -e file.txt ]] ; echo "$?" Prints 0 if file is there. This is necessary to include as part of the answer because otherwise people won't know how to store the boolean. – Timothy Swan Jan 04 '18 at 22:52
  • Note the importance of the space... "if [ "$the_world_is_flat"=true ]" (no space around = operator) will always be true. This gets me every time – tahiche Apr 06 '20 at 15:31
  • 1
    Super casual flat earther comment, nothing to see here – Jemar Jones Oct 21 '20 at 19:17
  • Doesn't the single = inside the [] need to be doubled == ? – zaTricky Mar 26 '21 at 10:03
  • Not assigning `the_world_is_flat` first still works as expected. Why? I'd expect the condition evaluation to result in a syntax error. – Gauthier May 27 '21 at 12:28
  • would it be same if I apply it for `false`? – alper Nov 07 '21 at 20:05
  • There's a serious exception - the_world_is_flat = true surely would cause the exception stupidity=true to also be false. – Tom Shaw Jun 12 '22 at 14:05
1168

TL;DR

my_bool=true

if [ "$my_bool" = true ]

Issues with Miku's (original) answer

I do not recommend the accepted answer1. Its syntax is pretty, but it has some flaws.

Say we have the following condition.

if $var; then
  echo 'Muahahaha!'
fi

In the following cases2, this condition will evaluate to true and execute the nested command.

# Variable var not defined beforehand. Case 1
var=''  # Equivalent to var="".      # Case 2
var=                                 # Case 3
unset var                            # Case 4
var='<some valid command>'           # Case 5

Typically you only want your condition to evaluate to true when your "Boolean" variable, var in this example, is explicitly set to true. All the other cases are dangerously misleading!

The last case (#5) is especially naughty because it will execute the command contained in the variable (which is why the condition evaluates to true for valid commands3, 4).

Here is a harmless example:

var='echo this text will be displayed when the condition is evaluated'
if $var; then
  echo 'Muahahaha!'
fi

# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!

Quoting your variables is safer, e.g. if "$var"; then. In the above cases, you should get a warning that the command is not found. But we can still do better (see my recommendations at the bottom).

Also see Mike Holt's explanation of Miku's original answer.

Issues with Hbar's answer

This approach also has unexpected behavior.

var=false
if [ $var ]; then
  echo "This won't print, var is false!"
fi

# Outputs:
# This won't print, var is false!

You would expect the above condition to evaluate to false, thus never executing the nested statement. Surprise!

Quoting the value ("false"), quoting the variable ("$var"), or using test or [[ instead of [, do not make a difference.

What I do recommend:

Here are ways I recommend you check your "Booleans". They work as expected.

my_bool=true

if [ "$my_bool" = true ]; then
if [ "$my_bool" = "true" ]; then

if [[ "$my_bool" = true ]]; then
if [[ "$my_bool" = "true" ]]; then
if [[ "$my_bool" == true ]]; then
if [[ "$my_bool" == "true" ]]; then

if test "$my_bool" = true; then
if test "$my_bool" = "true"; then

They're all pretty much equivalent. You'll have to type a few more keystrokes than the approaches in the other answers5, but your code will be more defensive.


Footnotes

  1. Miku's answer has since been edited and no longer contains (known) flaws.
  2. Not an exhaustive list.
  3. A valid command in this context means a command that exists. It doesn't matter if the command is used correctly or incorrectly. E.g. man woman would still be considered a valid command, even if no such man page exists.
  4. For invalid (non-existent) commands, Bash will simply complain that the command wasn't found.
  5. If you care about length, the first recommendation is the shortest.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
Dennis
  • 56,821
  • 26
  • 143
  • 139
  • 13
    Using `==` with `[` or `test` is not portable. Considering portability is the only advantage `[`/`test` has over `[[`, stick with `=`. – chepner Apr 30 '14 at 12:29
  • 2
    @Scott I use [fish](http://fishshell.com/) as my primary shell, which has a sane scripting language compared to bash in my opinion. – Dennis Jan 11 '15 at 05:10
  • @Kranach that's expected output and what I consider a valid command even though the `man` command is used incorrectly. If it were invalid, you would see `man: command not found`. That's what I mean with footnote #3. (Edit: Posted this before I saw your edit :)) – Dennis Jan 20 '15 at 16:40
  • 2
    Yeah, I just couldn't find in comments any appreciation for this hidden joke, so had to point it out =) – Kranach Jan 20 '15 at 17:01
  • 11
    For me, conceptually it is easier to understand if I use bool="true". Then it's clear that it's just a string and not some special value or builtin. – wisbucky Jun 09 '15 at 23:54
  • 1
    If `var` is a local variable where assignments are completely controlled in your program, there is no risk in using @miku's answer without quotes. – dolmen Mar 04 '16 at 13:40
  • 1
    @dolmen absolutely, evaluating input isn't as risky when you control the input, but I still consider it a bad practice that should be avoided if it can easily be avoided. Someone who has only ever seen and used the former style may not know about its flaws which can cause unexpected behaviour. – Dennis Mar 04 '16 at 14:34
  • 1
    Answers like these and Contributors like you make Stack Overflow the best place for devs. Thank you! – San May 09 '19 at 15:21
  • Worth noting that equality evaluates to `1` and so these conditions actually check the opposite of what they would in most other programming languages? – matanster Sep 09 '19 at 17:09
  • @Dennis Since the OP also wanted to check for false, it would be helpful for this highly rated answer to present recommended ways to test for false, rather than just use an example with false to blow up another answer here. – Bill Gale Mar 29 '21 at 20:11
  • I usually use this way: `a=true` and I evaluate like this `if [ "$a" = 'true' ]; then`. In our recommendation you used `if [ "$my_bool" = true ]; then` and `if [ "$my_bool" = "true" ]; then` It is my way wrong? why you didn't use simple quotes `'true'` but double quotes `"true"`? – Teocci Nov 24 '21 at 05:36
202

There seems to be some misunderstanding here about the Bash builtin true, and more specifically, about how Bash expands and interprets expressions inside brackets.

The code in miku's answer has absolutely nothing to do with the Bash builtin true, nor /bin/true, nor any other flavor of the true command. In this case, true is nothing more than a simple character string, and no call to the true command/builtin is ever made, neither by the variable assignment, nor by the evaluation of the conditional expression.

The following code is functionally identical to the code in the miku's answer:

the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
    echo 'Be careful not to fall off!'
fi

The only difference here is that the four characters being compared are 'y', 'e', 'a', and 'h' instead of 't', 'r', 'u', and 'e'. That's it. There's no attempt made to call a command or builtin named yeah, nor is there (in miku's example) any sort of special handling going on when Bash parses the token true. It's just a string, and a completely arbitrary one at that.

Update (2014-02-19): After following the link in miku's answer, now I see where some of the confusion is coming from. Miku's answer uses single brackets, but the code snippet he links to does not use brackets. It's just:

the_world_is_flat=true
if $the_world_is_flat; then
  echo 'Be careful not to fall off!'
fi

Both code snippets will behave the same way, but the brackets completely change what's going on under the hood.

Here's what Bash is doing in each case:

No brackets:

  1. Expand the variable $the_world_is_flat to the string "true".
  2. Attempt to parse the string "true" as a command.
  3. Find and run the true command (either a builtin or /bin/true, depending on the Bash version).
  4. Compare the exit code of the true command (which is always 0) with 0. Recall that in most shells, an exit code of 0 indicates success and anything else indicates failure.
  5. Since the exit code was 0 (success), execute the if statement's then clause

Brackets:

  1. Expand the variable $the_world_is_flat to the string "true".
  2. Parse the now-fully-expanded conditional expression, which is of the form string1 = string2. The = operator is bash's string comparison operator. So...
  3. Do a string comparison on "true" and "true".
  4. Yep, the two strings were the same, so the value of the conditional is true.
  5. Execute the if statement's then clause.

The no-brackets code works, because the true command returns an exit code of 0, which indicates success. The bracketed code works, because the value of $the_world_is_flat is identical to the string literal true on the right side of the =.

Just to drive the point home, consider the following two snippets of code:

This code (if run with root privileges) will reboot your computer:

var=reboot
if $var; then
  echo 'Muahahaha! You are going down!'
fi

This code just prints "Nice try." The reboot command is not called.

var=reboot
if [ $var ]; then
  echo 'Nice try.'
fi

Update (2014-04-14) To answer the question in the comments regarding the difference between = and ==: AFAIK, there is no difference. The == operator is a Bash-specific synonym for =, and as far as I've seen, they work exactly the same in all contexts.

Note, however, that I'm specifically talking about the = and == string comparison operators used in either [ ] or [[ ]] tests. I'm not suggesting that = and == are interchangeable everywhere in bash.

For example, you obviously can't do variable assignment with ==, such as var=="foo" (well technically you can do this, but the value of var will be "=foo", because Bash isn't seeing an == operator here, it's seeing an = (assignment) operator, followed by the literal value ="foo", which just becomes "=foo").

Also, although = and == are interchangeable, you should keep in mind that how those tests work does depend on whether you're using it inside [ ] or [[ ]], and also on whether or not the operands are quoted. You can read more about that in Advanced Bash Scripting Guide: 7.3 Other Comparison Operators (scroll down to the discussion of = and ==).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike Holt
  • 4,452
  • 1
  • 17
  • 24
  • The no-bracket approach also has the advantage of letting you write clean, clear (imo) one-liners like `$the_world_is_flat && echo "you are in flatland!"` – ajk Feb 20 '14 at 01:11
  • 10
    True. Although, I'm not advocating for (or against) either approach. I just wanted to clear up some of the misinformation that's getting voted up here, so that people who stumble upon this topic later on won't walk away with a bunch of misconceptions about how this all works. – Mike Holt Feb 20 '14 at 01:19
  • Using `==` with `[`/`test` is not portable; if you want to use `==`, use `[[`. If you want to use `[`, use `=`. – chepner Apr 30 '14 at 12:32
  • @chepner You're right. I hate `==` and never use it in my own scripts. Not sure why I had that in there. Maybe just too much C on the brain. – Mike Holt Apr 30 '14 at 14:56
  • 1
    The reason for the confusion is that miku's original answer stood for 4 years. All the references to the builtin `true` were made regarding the original answer. (The revised answer on Feb 12, 2014 was not submitted by miku.) I have edited the answer to include both original and revised. Then people's comments make sense. – wisbucky Jun 08 '15 at 23:10
  • @wisbucky Thanks for that. I hadn't realized that there was a prior version of miku's answer, although I did note in my update on 2/19/2014 that the article linked to in miku's answer was doing something different. – Mike Holt Jun 08 '15 at 23:49
  • 1
    From reading the answers offered here, I get the impression that there's no such thing as actually using the real `true`. Is there a way? I suspect many programmers who are used to stricter languages viewing this answer to assist them in mixing up some `bash` glue to make their lives a bit easier would want an `===` operator so that strings and "booleans" aren't actually interchangeable. Should they just stick to 0 and 1 and use `(( $maybeIAmTrue ))` as suggested in [Quolonel Question](http://stackoverflow.com/users/1041515)'s [answer](http://stackoverflow.com/a/26920580/3159183)? – Seldom 'Where's Monica' Needy Jul 23 '15 at 23:59
  • wouldnt it make more sense to use `0` and `1` instead of `false` and `true` then? aka `if [[ $a == 0 ]]; then ..` – phil294 Jul 24 '17 at 19:31
  • 3
    To address SeldomNeedy's comment, yes, you can use the real `true`, but generally not as something to compare a variable against, since the real `true` has no value per se. All it does is set the exit status to `0`, indicating success. It's worth noting that it's essentially equivalent to the so-called "null command", or `:`. As far as using `0` and `1`, that's what I do in all my scripts these days where I need booleans. And I use the `(( ))` operator instead of `[[ ]]` to evaluate. So, for example, if I have `flag=0`, I can then do `if (( flag )); then ...` – Mike Holt Jul 24 '17 at 19:58
91

Use arithmetic expressions.

#!/bin/bash

false=0
true=1

((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true

Output:

true
not false

Quolonel Questions
  • 6,603
  • 2
  • 32
  • 33
  • 4
    pros: (1.) behaviour is similar to C's way of handling bools, (2.) syntax is very concise/minimal (does not require a right-hand variable and operators like '=' or '=='), (3.) for me I understand what happens without a long winded explanation ... contrast to Miku and Dennis' answers which both seem to require long winded explanations – Trevor Boyd Smith May 25 '15 at 12:23
  • 6
    @TrevorBoydSmith Why didn't you just say, "pros: everything, cons: nothing". Would save depreciation costs on your keyboard and monitor in the long run. – Quolonel Questions May 26 '15 at 13:03
  • 7
    For interactive use, like one-liners, make sure to leave a space after `!`, or it will do history expansion. `((! foo))` works, so does `! ((foo))`. I love this solution, BTW. Finally a concise way to do boolean variables. `((foo || bar))` works as expected. – Peter Cordes Sep 05 '15 at 05:42
  • 7
    `(())` expands variables recursively, which I wasn't expecting. `foo=bar; bar=baz; ((foo)) && echo echo` prints nothing, but it's true with `baz=1`. So you can support `foo=true` and `foo=false` as well as 0 or 1 by doing `true=1`. – Peter Cordes Sep 05 '15 at 06:02
  • 1
    Big downside of this: The double braces have exit code 1 if the result of the expression is 0, so if you are using strict error checking (`set -e`), which you totally should, this will lead to unforeseen errors. – Hubert Grzeskowiak Nov 03 '17 at 09:19
  • 1
    Also you can't use test flags (see `man test`) with this. It is for arithmetical expressions only – Hubert Grzeskowiak Nov 03 '17 at 09:22
  • @HubertGrzeskowiak Since you have demonstrated very limited understanding I suggest you read [why set -e is a bad idea](http://mywiki.wooledge.org/BashFAQ/105). – Quolonel Questions Nov 03 '17 at 13:28
  • 2
    @quolonel thank you for the very helpful resource. Of course my understanding is limited - it is human nature to be limited in all understanding no matter the domain. However, would you mind telling me which of my statements lead you to the assumption that my understanding of this particular matter is incomplete? – Hubert Grzeskowiak Nov 03 '17 at 13:55
  • 1
    I think I am well aware of the implications of '-e' and I would still recommend it for multiple reasons – Hubert Grzeskowiak Nov 03 '17 at 13:56
  • 2
    In case you are referring to the exception of certain chained commands from the special error-intolerant mode, I think relying on the next editor to know these implications is too risky and not worth the seemingly better syntax. I've seen arithmetic expressions on their own line a few times too much, I guess – Hubert Grzeskowiak Nov 03 '17 at 13:59
  • I write this script for print greating on the first time (usefull in huge directory for command to signal progress). `limit=10 first=1 for ((i=1;i<=$limit;i++)); do ((first)) && echo "Hello" && first=0 echo $i done ` – alfiogang Jun 07 '19 at 08:01
  • `((Debug)) && echo stuff` is so much simpler than the longer version`[[ "$fDebug" == true ]] && echo stuff`. You've got my vote. – WinEunuuchs2Unix Jun 30 '19 at 17:38
  • Does not work for me. It returns `true` and `not true`?! `ash-4.3# false=0 ash-4.3# true=1 ash-4.3# ((false)) && echo false ash-4.3# ((true)) && echo true true ash-4.3# ((!false)) && echo not false ((false=0)) && echo not false ash-4.3# ((!true)) && echo not true ((true=1)) && echo not true not true` – mgutt Aug 08 '19 at 11:09
  • `sh --help` returns `GNU bash, version 4.3.48(1)-release-(x86_64-pc-linux-gnu)` so its simply bash (this is the shell of a Synology NAS). And the question was related a "shell" and not specific shell variant. So in which shell does your code work? – mgutt Aug 09 '19 at 11:30
  • 1
    There is one problem with this: invalid values cause syntax errors, e.g. `s=/home; ((s))` outputs `bash: ((: /home: syntax error: operand expected (error token is "/home")` – wjandrea Sep 02 '19 at 02:20
  • 5
    @wjandrea That's the opposite of a problem because now you have a mechanism to identify bugs in your code. – Quolonel Questions Sep 02 '19 at 06:45
  • This answer is the closest to the OP where they were interested in if ! variable and the arithmetic expressions support that. All the string approaches suffer from having to do string companions to "false" or using else constructs, if you interest is in false only, an else construct would be an awkward way to achieve that. – Bill Gale Mar 29 '21 at 19:59
89

Long story short:

There are no Booleans in Bash

The true and false commands

Bash does have Boolean expressions in terms of comparison and conditions. That said, what you can declare and compare in Bash are strings and numbers. That's it.

Wherever you see true or false in Bash, it's either a string or a command/builtin which is only used for its exit code.

This syntax...

if true; then ...

is essentially...

if COMMAND; then ...

where the command is true. The condition is true whenever the command returns exit code 0. true and false are Bash builtins and sometimes also standalone programs that do nothing but returning the corresponding exit code.


Conditions in if..then..fi

When using square brackets or the test command, you rely on the exit code of that construct. Keep in mind that [ ] and [[ ]] are also just commands/builtins like any other. So ...

if [[ 1 == 1 ]]; then echo yes; fi

corresponds to

if COMMAND; then echo yes; fi

and the COMMAND here is [[ with the parameters 1 == 1 ]]

The if..then..fi construct is just syntactic sugar. You can always just run the commands separated by a double ampersand for the same effect:

[[ 1 == 1 ]] && echo yes

When using true and false in these testing constructs you are actually only passing the string "true" or "false" to the testing command. Here is an example:

Believe it or not but those conditions are all yielding the same result:

if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...

TL;DR; always compare against strings or numbers

To make this clear to future readers, I would recommend always using quotes around true and false:

DO

if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ "${var}" == "yes" ]]; then ...
if [[ "${var}" == "USE_FEATURE_X" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...

DON'T

# Always use double square brackets in bash!
if [ ... ]; then ...
# This is not as clear or searchable as -n
if [[ "${var}" ]]; then ...
# Creates impression of Booleans
if [[ "${var}" != true ]]; then ...
# `-eq` is for numbers and doesn't read as easy as `==`
if [[ "${var}" -eq "true" ]]; then ...

Maybe

# Creates impression of Booleans.
# It can be used for strict checking of dangerous operations.
# This condition is false for anything but the literal string "true".
if [[ "${var}" != "true" ]]; then ... 
Hubert Grzeskowiak
  • 15,137
  • 5
  • 57
  • 74
  • I prefer to use `T` and `F` to make clear that those aren't real boolean values. – phk Feb 16 '18 at 12:57
  • 2
    I can't agree with "always use double brackets in bash". In fact in almost all the scripts I've written I am using single brackets, except when I need to do pattern matching. I think one should understand the difference between `[`(i.e. `test`) and `[[` and use the one that is suitable for his need. – Weijun Zhou May 12 '20 at 12:43
  • @WeijunZhou mind elaborating in which cases single brackets are better? – Hubert Grzeskowiak May 12 '20 at 23:07
  • It's more of a personal taste, I just find that it is too bold to say "Always use double square brackets in bash". But there are some edge cases that I have used. Single brackets allow you to specify the test itself in a var. As an oversimplified example, consider `if ....; then mytest='-gt'; else mytest='-eq'; fi; #several lines of code; if [ "$var1" "$mytest" "$var2" ]; then ...; fi` – Weijun Zhou May 12 '20 at 23:29
  • 1
    @WeijunZhou Your example is a strong argument against single square brackets. It makes the code much harder to understand and opens the window wide open to errors. Double brackets are more strict and encourage cleaner code. – Hubert Grzeskowiak May 13 '20 at 04:47
  • @WeijunZhou your code can be vey easily refactored to not require a dynamic comparison. – Hubert Grzeskowiak May 13 '20 at 04:48
  • Actually I wanted to quote https://stackoverflow.com/a/47576482/3966456 at my first reply. The main point being "There are POSIX equivalents for every [[ ]] construct I've seen." As there is another whole question for this matter, and as you see people clearly have different opinions on this, Plus I never really have to worry whether my use of single brackets has errors now that I have shellcheck. I think it's better to just stop here, or move the discussion to the cited question. I did not add my example as an answer/comment to that question precisely because I know it would be controversial. – Weijun Zhou May 13 '20 at 10:28
  • I think I will rewrite my comment posted before the last one (and that one will be deleted) to clarify my point. Admittedly the example I gave is an edge case, not something that you would do excessively in production code. My point is, I don't like the restriction `[[` puts on me by auto-quoting variables and escaping parenthesis because that closes a lot of possibilities. Additionally, such auto-escaping is inconsistent with other parts of bash. If I have an unquoted variable in `[[`, I want it to bite me the first time I write it, not later when I change the `if` to something else. – Weijun Zhou May 13 '20 at 11:10
  • 1
    This answer above all the others helped me understand some core concepts. The idea that `[` is a built-in that returns an exit code based on evaluating its expression is important; and the "aha" moment for me is the builtins true, and false, are the same. Thus, you can do simple boolean checks if you assign true or false directly to variables and use them *without brackets*: `if $my_bool ; then` or `$my_bool && echo "Print this"`. Exit code 0 and exit code 1, that's all you get from your true/false here. Clicked for me. Thanks! – trisweb Jul 07 '23 at 01:17
25

Long ago, when all we had was sh, Booleans where handled by relying on a convention of the test program where test returns a false exit status if run without any arguments.

This allows one to think of a variable that is unset as false and variable set to any value as true. Today, test is a builtin to Bash and is commonly known by its one-character alias [ (or an executable to use in shells lacking it, as dolmen notes):

FLAG="up or <set>"

if [ "$FLAG" ] ; then
    echo 'Is true'
else
    echo 'Is false'
fi

# Unset FLAG
#    also works
FLAG=

if [ "$FLAG" ] ; then
    echo 'Continues true'
else
    echo 'Turned false'
fi

Because of quoting conventions, script writers prefer to use the compound command [[ that mimics test, but has a nicer syntax: variables with spaces do not need to be quoted; one can use && and || as logical operators with weird precedence, and there are no POSIX limitations on the number of terms.

For example, to determine if FLAG is set and COUNT is a number greater than 1:

FLAG="u p"
COUNT=3

if [[ $FLAG  && $COUNT -gt '1' ]] ; then
    echo 'Flag up, count bigger than 1'
else
    echo 'Nope'
fi

This stuff can get confusing when spaces, zero length strings, and null variables are all needed and also when your script needs to work with several shells.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hbar
  • 443
  • 4
  • 7
  • 3
    `[` is not just an alias inside `bash`. This alias also exists as a binary file (or as a link pointing to) and can be used with the bare `sh`. Check `ls -l /usr/bin/\[`. With `bash`/`zsh` you should instead use `[[` that is a true pure internal and is much more powerful. – dolmen May 13 '13 at 12:49
  • 2
    @dolmen `[` and `test` is also a Bash SHELL BUILTIN COMMAND according to Bash manual page, so there should not be an issue in performance. Same thing with e.g. Dash. (/bin/sh may just a symlink to /bin/dash). To use the executable you have to use full path i.e. `/usr/bin/\[`. – jarno Mar 02 '16 at 09:43
14

How can I declare and use Boolean variables in a shell script?

Unlike many other programming languages, Bash does not segregate its variables by "type." [1]

So the answer is pretty clear. There isn't any Boolean variable in Bash.

However:

Using a declare statement, we can limit the value assignment to variables.[2]

#!/bin/bash
declare -ir BOOL=(0 1) # Remember BOOL can't be unset till this shell terminates
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}

# Same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"

The r option in declare and readonly is used to state explicitly that the variables are readonly. I hope the purpose is clear.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • 1
    Why don't you just do `declare -ir false=0 true=1`? What's the advantage of using an array? – Benjamin W. Apr 30 '16 at 06:29
  • 1
    @BenjaminW. I just wanted to mention about the `r` option & `readonly` command. I would do it the way you suggested in my scripts – sjsam Apr 30 '16 at 06:49
  • maybe I missed something but why dont true and false declared in this way use the dollar sign? $true $false – qodeninja Dec 15 '17 at 17:44
  • Literally just copying my answer and making it worse. – Quolonel Questions Mar 04 '19 at 23:36
  • @QuolonelQuestions Bash variables are not **typed**, hence there is no point in saying `declare and use boolean variables`.We could just, in more than one way, mimic/assume that a variable has a **type**. I didn't see that mentioned anywhere in your answer. – sjsam Mar 06 '19 at 11:49
  • @qodeninja In bash you never use the `$` when declaring -- only when evaluating. – Jonathan Cross May 10 '20 at 13:27
13

Instead of faking a Boolean and leaving a trap for future readers, why not just use a better value than true and false?

For example:

build_state=success
if something-horrible; then
  build_state=failed
fi

if [[ "$build_state" == success ]]; then
  echo go home; you are done
else
  echo your head is on fire; run around in circles
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pyrolistical
  • 27,624
  • 21
  • 81
  • 106
  • why not integers? – phil294 Jul 24 '17 at 19:32
  • 6
    @Blauhirn because integers are used differently depending on languages. In some languages `0` coerces to `false` and `1` to `true`. In regards to program exit codes (which bash historically uses) it's `0` for positive outcome or `true` and everything else is negative/error or `false`. – Hubert Grzeskowiak Nov 03 '17 at 09:26
12

My findings and suggestion differ a bit from the other posts. I found that I could use "booleans" basically as one would in any "regular" language, without the "hoop jumping" suggested...

There isn't any need for [] or explicit string comparisons... I tried multiple Linux distributions. I tested Bash, Dash, and BusyBox. The results were always the same. I'm not sure what the original top voted posts are talking about. Maybe times have changed and that's all there is to it?

If you set a variable to true, it subsequently evaluates as an "affirmative" within a conditional. Set it to false, and it evaluates to a "negative". Very straightforward! The only caveat, is that an undefined variable also evaluates like true! It would be nice if it did the opposite (as it would in most languages), but that's the trick - you just need to explicitly initialize your booleans to true or false.

Why does it work this way? That answer is two fold. A) true/false in a shell really means "no error" vs "error" (i.e. 0 vs anything else). B) true/false are not values - but rather statements in shell scripting! Regarding the second point, executing true or false on a line by itself sets the return value for the block you're in to that value, i.e. false is a declaration of "error encountered", where true "clears" that. Using it with an assignment to a variable "returns" that into the variable. An undefined variable evaluates like true in a conditional because that equally represents 0 or "no error encountered".

See the example Bash lines and results below. Test it yourself if you want to confirm...

#!/bin/sh

# Not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

Yields

when set to
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false
BuvinJ
  • 10,221
  • 5
  • 83
  • 96
9

POSIX (Portable Operating System Interface)

I miss here the key point, which is portability. That's why my header has POSIX in itself.

Essentially, all of the voted answers are correct, with the exception they are Bash-specific too much.

Basically, I only wish to add more information about portability.


  1. [ and ] brackets like in [ "$var" = true ] are not necessary, and you can omit them and use the test command directly:

    test "$var" = true && yourCodeIfTrue || yourCodeIfFalse
    

    Important note: I no longer recommend this as it's being slowly deprecated and more difficult to combine multiple statements.

  2. Imagine what those words true and false mean to the shell, test it yourself:

    echo $(( true ))
    
    0
    
    echo $(( false ))
    
    1
    

    But using quotes:

    echo $(( "true" ))
    
    bash: "true": syntax error: operand expected (error token is ""true"")
    sh (dash): sh: 1: arithmetic expression: expecting primary: ""true""
    

    The same goes for:

    echo $(( "false" ))
    

    The shell can't interpret it other than a string. I hope you are getting the idea of how good it is using proper keyword without quotes.

    But no one said it in previous answers.

  3. What does this mean? Well, several things.

    • You should get used to the Boolean keywords are actually treated like numbers, that is true = 0 and false = 1, remember all non-zero values are treated like false.

    • Since they are treated as numbers, you should treat them like that too, i.e. if you define variable say:

      var_bool=true
      echo "$var_bool"
      
       true
      

      you can create an opposite value of it with:

      var_bool=$(( 1 - $var_bool ))  # same as $(( ! $var_bool ))
      echo "$var_bool"
      
      1
      

    As you can see for yourself, the shell does print true string for the first time you use it, but since then, it all works via number 0 representing trueor 1 representing false, respectively.


Finally, what you should do with all that information

  • First, one good habit would be assigning 0 instead of true; 1 instead of false.

  • Second good habit would be to test if the variable is / isn't equal to zero:

    if [ "$var_bool" -eq 0 ]; then
         yourCodeIfTrue
    else
         yourCodeIfFalse
    fi
    
Vlastimil Burián
  • 3,024
  • 2
  • 31
  • 52
8

In many programming languages, the Boolean type is, or is implemented as, a subtype of integer, where true behaves like 1 and false behaves like 0:

Mathematically, Boolean algebra resembles integer arithmetic modulo 2. Therefore, if a language doesn't provide native Boolean type, the most natural and efficient solution is to use integers. This works with almost any language. For example, in Bash you can do:

# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false

man bash:

((expression))

The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "expression".

Community
  • 1
  • 1
Cyker
  • 9,946
  • 8
  • 65
  • 93
6

Regarding syntax, this is a simple methodology that I use (by example) to consistently and sanely manage Boolean logic:

# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc

if [[ -n "${var}" ]] ; then
    echo 'true'
fi
if [[ -z "${var}" ]] ; then
    echo 'false'
fi

# Results
# var=        # false
# var=''      # false
# var=""      # false
# var=0       # true
# var=1       # true
# var="abc"   # true
# var=abc     # true

If the variable is never declared the answer is: # false

So, a simple way to set a variable to true (using this syntax methodology) would be, var=1; conversely, var=''.

Reference:

-n = True if the length of var string is non-zero.

-z = True if the length of var string is zero.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Eric P
  • 588
  • 5
  • 9
5

Bill Parker is getting voted down, because his definitions are reversed from the normal code convention. Normally, true is defined as 0 and false is defined as nonzero. 1 will work for false, as will 9999 and -1. The same with function return values - 0 is success and anything nonzero is failure. Sorry, I don't have the street credibility yet to vote or to reply to him directly.

Bash recommends using double brackets now as a habit instead of single brackets, and the link Mike Holt gave explains the differences in how they work. 7.3. Other Comparison Operators

For one thing, -eq is a numerical operator, so having the code

#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

will issue an error statement, expecting an integer expression. This applies to either parameter, as neither is an integer value. Yet, if we put double brackets around it, it will not issue an error statement, but it will yield a wrong value (well, in 50% of the possible permutations). It will evaluate to [[0 -eq true]] = success, but also to [[0 -eq false]] = success, which is wrong (hmmm.... what about that builtin being a numerical value?).

#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then

There are other permutations of the conditional which will give wrong output as well. Basically, anything (other than the error condition listed above) that sets a variable to a numerical value and compares it to a true/false builtin, or sets a variable to a true/false builtin and compares it to a numerical value. Also, anything that sets a variable to a true/false builtin and does a comparison using -eq. So avoid -eq for Boolean comparisons and avoid using numerical values for Boolean comparisons. Here's a summary of the permutations that will give invalid results:

# With variable set as an integer and evaluating to true/false
# *** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

# With variable set as an integer and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then


# With variable set as an true/false builtin and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then

So, now to what works. Use true/false builtins for both your comparison and your evaluations (as Mike Hunt noted, don't enclose them in quotes). Then use either or single or double equal sign (= or ==) and either single or double brackets ([ ] or [[ ]]). Personally, I like the double equals sign, because it reminds me of logical comparisons in other programming languages, and double quotes just because I like typing. So these work:

# With variable set as an integer and evaluating to true/false
# *** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

There you have it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Randyman99
  • 305
  • 4
  • 2
  • 2
    The `true`/`false` built-ins aren't used here (ignore what the syntax highlighting of some editors might imply), especially in the `[…]` cases you can think of it as a simple string here (one that is given as a parameter to the `[` command). – phk Sep 25 '16 at 16:02
  • You have it now. – Peter Mortensen Jan 01 '20 at 12:43
4

Another way of using booleans is to test the emptyness of values. This has the advantage of making shorter tests:

first=1  # A true value
second=   # A false value

[ -n "$first" ]  && echo 'First var is true'
[ -z "$first" ]  && echo 'First var is false'
[ -n "$second" ] && echo 'Second var is true'
[ -z "$second" ] && echo 'Second var is false'

Output:

First var is true
Second var is false

Here is an alternative test syntax with bash: [[ -n $one ]]

yolenoyer
  • 8,797
  • 2
  • 27
  • 61
3

My receipe to (my own) idiocy:

# setting ----------------
commonMode=false
if [[ $something == 'COMMON' ]]; then
    commonMode=true
fi

# using ----------------
if $commonMode; then
    echo 'YES, Common Mode'
else
    echo 'NO, no Common Mode'
fi

$commonMode && echo 'commonMode is ON  ++++++'
$commonMode || echo 'commonMode is OFF xxxxxx'
Frank N
  • 9,625
  • 4
  • 80
  • 110
2

Here is an improvement on miku's original answer that addresses Dennis Williamson's concerns about the case where the variable is not set:

the_world_is_flat=true

if ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

And to test if the variable is false:

if ! ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

About other cases with a nasty content in the variable, this is a problem with any external input fed to a program.

Any external input must be validated before trusting it. But that validation has to be done just once, when that input is received.

It doesn't have to impact the performance of the program by doing it on every use of the variable like Dennis Williamson suggests.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dolmen
  • 8,126
  • 5
  • 40
  • 42
  • I like this answer, it's simple and almost works in all the cases (except if the variable is a non-empty string or a valid command). – Míng Oct 12 '22 at 08:43
2

In most cases you need "boolean" for boolean operations, such as ! && or ||. In some languages special boolean type do not exists at all (because in fact you do not need it technically), in most of interpreted languages (almost) all types automatically converted to some kind of boolean in operations like ! && or ||.

Boolean always is something that works with boolean operations. In Bash such operations are (no "" around $var, it's very important!):

[[ $var ]] - check if var is true
[[ ! $var ]] - check if var is false
[[ $var1 || $var2 ]] - var1 or var2
[[ $var1 && $var2 ]] - var1 and var2

[[ $var ]] is false only if var='' (or unset). So the only one correct 'false' value of variable in bash is '' (empty string). For true you can select any value, but I prefer var=1 (like in other languages, where true is any not-null int, but for readable purposes programmers always use 1).

NOTE: for var='false' var in boolean checks is true. In Bash string 'false' is actually true (same as in all other languages!). The only one difference between Bash and, e.g. Python, Perl or PHP, is that in Bash 0 is also true. But again: there are boolean operations in Bash, and they works like in all other interpreted languages, except that 0 in Bash is true.

It's absolutely irrational to use strings 'true' and 'false' as boolean replacement in Bash. It's like using same strange concept in Python, or Perl, or PHP. It works slower (in Bash too), and nobody do it in other languages, but in Bash there are a lot of coders that think it's a good solution. No. There are no reasons not to use boolean operations in Bash directly, without absolutely strange comparisons like $var == 'true' or $var == 'false'.

So again, boolean replacements in Bash are:

var=''  # false
var=1   # true (actually any non-empty string)

And direct usage of boolean checks in Bash also is a fastest way to do boolean-like checks. All other constructions will works much slower.

P.S. "old" style of "boolean" checks like a=true; if $a; then ... are absolutely idiotic, because:

  1. you can't use them directly in conditions [[ ]]
  2. they act as eval of bash code, stored in variable. Well, if you think it's a good idea, just do not ever write any program, please;)

P.P.S. If $var can be unset and you use very helpful set -u just replace $var in checks to ${var-}, e.g. [[ ${var-} ]] (also: no "" around, it's important for speed of code execution!)

Malamut
  • 39
  • 3
1

I found the existing answers confusing.

Personally, I just want to have something which looks and works like C.

This snippet works many times a day in production:

snapshotEvents=true

if ($snapshotEvents)
then
    # Do stuff if true
fi

and to keep everyone happy, I tested:

snapshotEvents=false

if !($snapshotEvents)
then
    # Do stuff if false
fi

Which also worked fine.

The $snapshotEvents evaluates the contents of value of the variable. So you need the $.

You don't really need the parentheses, I just find them helpful.

will
  • 4,799
  • 8
  • 54
  • 90
  • 2
    Where you remove the parentheses, this is exactly @miku's original answer at the top. – dolmen Mar 04 '16 at 13:56
  • 1
    Without parentheses the expression doesn't evaluate. – will Mar 06 '16 at 11:01
  • @will yes it does. You dont need the ()s. – phil294 Nov 03 '17 at 17:00
  • 1
    @Blauhirn ... Hi, I based my comments on experiments with GNU Bash on a Linux Mint /Ubuntu PC. You are probably right in _theory_ `()`-s are not needed. My only response, is try it out, it seems to _depend_ on Bash version, the actual expression or context and such. – will Nov 06 '17 at 07:13
  • This is obviously (to me) the most clear syntax, but there's gotta be a catch somewhere. I don't think it works with integer values: `> bucket_available=0; > if ($bucket_available); then echo hi; fi bash: 0: command not found` – Max Cascone May 19 '23 at 16:11
1

Here is a simple example which works for me:

temp1=true
temp2=false

if [ "$temp1" = true ] || [ "$temp2" = true ]
then
    echo "Do something." 
else
    echo "Do something else."
fi
Vlastimil Burián
  • 3,024
  • 2
  • 31
  • 52
Harsimranjit Singh Kler
  • 2,006
  • 1
  • 18
  • 21
1

Here is an implementation of a short handed if true.

# Function to test if a variable is set to "true"
_if () {
    [ "${1}" == "true" ] && return 0
    [ "${1}" == "True" ] && return 0
    [ "${1}" == "Yes" ] && return 0
    return 1
}

Example 1

my_boolean=true

_if ${my_boolean} && {
    echo "True Is True"
} || {
    echo "False Is False"
}

Example 2

my_boolean=false
! _if ${my_boolean} && echo "Not True is True"
llundin
  • 383
  • 2
  • 13
1

You can use shFlags.

It gives you the option to define: DEFINE_bool

Example:

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");

From the command line you can define:

sh script.sh --bigmenu
sh script.sh --nobigmenu # False
gogasca
  • 9,283
  • 6
  • 80
  • 125
1

This is a speed test about different ways to test "Boolean" values in Bash:

#!/bin/bash
rounds=100000

b=true # For true; b=false for false
type -a true
time for i in $(seq $rounds); do command $b; done
time for i in $(seq $rounds); do $b; done
time for i in $(seq $rounds); do [ "$b" == true ]; done
time for i in $(seq $rounds); do test "$b" == true; done
time for i in $(seq $rounds); do [[ $b == true ]]; done

b=x; # Or any non-null string for true; b='' for false
time for i in $(seq $rounds); do [ "$b" ]; done
time for i in $(seq $rounds); do [[ $b ]]; done

b=1 # Or any non-zero integer for true; b=0 for false
time for i in $(seq $rounds); do ((b)); done

It would print something like

true is a shell builtin
true is /bin/true

real    0m0,815s
user    0m0,767s
sys     0m0,029s

real    0m0,562s
user    0m0,509s
sys     0m0,022s

real    0m0,829s
user    0m0,782s
sys     0m0,008s

real    0m0,782s
user    0m0,730s
sys     0m0,015s

real    0m0,402s
user    0m0,391s
sys     0m0,006s

real    0m0,668s
user    0m0,633s
sys     0m0,008s

real    0m0,344s
user    0m0,311s
sys     0m0,016s

real    0m0,367s
user    0m0,347s
sys     0m0,017s
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jarno
  • 787
  • 10
  • 21
1

You can use aliases and alias to the true and false builtins. Maybe a little unconventional but it seems like a nice clean solution to me.

alias my_bool=false

if [[ $(($RANDOM % 2)) == 0 ]]; then
  alias my_bool=true
fi

if my_bool; then
  echo 'true!'
else
  echo 'false!'
fi
cambunctious
  • 8,391
  • 5
  • 34
  • 53
1

The rest of answers are highly slow.

Do not check if a boolean variable equals to anything, but if it's empty or not.

#false:
condition=""

#true:
condition=x

#check:
[ -n "${condition}" ]
0
[[ "$x" == 'true' || "$x" -ne 0 ]] && ...

Is enough simple and has no dependencies.

Andry
  • 2,273
  • 29
  • 28
-1

Bash really confuses the issue with the likes of [, [[, ((, $((, etc.

All treading on each others' code spaces. I guess this is mostly historical, where Bash had to pretend to be sh occasionally.

Most of the time, I can just pick a method and stick with it. In this instance, I tend to declare (preferably in a common library file I can include with . in my actual script(s)).

TRUE=1; FALSE=0

I can then use the (( ... )) arithmetic operator to test thusly.

testvar=$FALSE

if [[ -d ${does_directory_exist} ]]
then
    testvar=$TRUE;
fi

if (( testvar == TRUE )); then
    # Do stuff because the directory does exist
fi
  1. You do have to be disciplined. Your testvar must either be set to $TRUE or $FALSE at all times.

  2. In (( ... )) comparators, you don't need the preceding $, which makes it more readable.

  3. I can use (( ... )) because $TRUE=1 and $FALSE=0, i.e. numeric values.

  4. The downside is having to use a $ occasionally:

    testvar=$TRUE
    

    which is not so pretty.

It's not a perfect solution, but it covers every case I need of such a test.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bill Parker
  • 765
  • 5
  • 4
  • 2
    You should declare your constants readonly. Also please always use curly brackets when using variables. It's a convention everyone should stick to IMHO. Big downside of this solution is that you cannot mix the algebraic expression with test flags or string comparisons. – Hubert Grzeskowiak Nov 03 '17 at 09:57
-2

Alternative - use a function

is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It's OK" || echo "Something's wrong"

Defining the function is less intuitive, but checking its return value is very easy.

johnraff
  • 327
  • 2
  • 5