1

Can someone explain how to perform Boolean operations and store them in variables in Bash?

I tried:

A=true
B=false
C=!$A
D=$A && $B
echo $C
echo $D

I also tried without dollars, with [], with {}, ()... How can one do such a simple operation in bash?

result in console are:

!true
true

It seems they are always treated as strings.

1
  • P.S. more or less 1st time I use bash ... Commented Oct 19, 2017 at 15:25

3 Answers 3

4

Unfortunately, bash does not support boolean variables in a proper meaning. There is no "true" and "false" constants as in programming languages. Instead, /bin/true and /bin/false are two executables that don't do anything except return exit status 0 or 1. Contrary to common logic, exit status 0 is a synonim for "true" and 1 is a synonim for "false". The closest you can get to evaluating boolean expressions is either

  • [[ expr ]] which returns a exit status 0 or 1 depending on evaluating expr
  • && and || (these are conditionals depending on last command's exit status)
  • [ which is actually an executable with a silly name (not part of bash) that supports some basic expressions
  • if...elif..else..fi which you can use to your advantage to manipulate variables within the workflow
Sign up to request clarification or add additional context in comments.

1 Comment

It's less of a contradiction if you think of 0 as success and non-zero as failure, rather than logical truth. [ is indeed a silly name; it's "real" name is test. (bash does additionally implement [/test internally for performance reasons, though.)
4

You deduced right, bash variables by default contain strings, and its values are treated as strings.

You can use the declare built-in command to explicitly say they store integers (declare -i myintvar), or indexed arrays (declare -a myarr), or associative arrays (declare -A mymap), etc., but not booleans.

The closest you can get to booleans is to use integer values 0 and 1 and evaluate expressions as arithmetic expressions with the (( expr )) command (bash-specific), or with arithmetic expansion $(( expr )) (POSIX-compatible). Those commands evaluate expr according to rules of shell arithmetic.

For example:

A=1
B=0
(( C = \!A ))       # logical negation  ==>  C = 0
(( D = A && B ))    # logical AND       ==>  D = 0
E=$(( A ^ B ))      # bitwise XOR       ==>  E = 1

In bash, you can also use declare -i and let:

declare -i E='A||B'    # equivalent to: E=$((A||B)), or ((E=A||B))
let C='!A'             # equivalent to: C=$((\!A)), or ((C=\!A))

which are a longer way of saying ((..)) or $((..)). They both force arithmetic evaluation of the expressions given.

Note that ! has a special meaning in most shells (including bash), it causes history expansion. To prevent it, we must escape it with a backslash, or quote it.

4 Comments

I would avoid the integer attribute; it's doesn't really provide any value. Your declare command doesn't do what you think; || is treated as the normal shell operator, so B is only executed if declare -i E=A fails. You need to quote the value: declare -i E="A||B" to have the intended effect of simulating E=$((A||B)).
Thanks, I missed the quotes there. Note that declare -i evaluates the expr as arithmetic.
So does E=$((A || B)), which is more explicit as well as being standard.
@chepner, I've updated my answer a little bit, hope the bash/posix difference is clearer now. Thanks.
0

like this?

t=true
f=false

# if $t; then echo Hi; fi
Hi
# if $f; then echo Hi; fi
# if ! $f; then echo Hi; fi
Hi
# if ! ($t && $t); then echo Hi; fi
# if  ($t && $t); then echo Hi; fi
Hi

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.