## 1. Overview

One of the most useful features of Bash is its support for conditional statements. Among these is the ternary operator or conditional operator, denoted by the *?* symbol. The ternary operator returns different values based on the evaluation of a condition.

In this tutorial, we’ll discuss how to use the ternary operator in Bash. Further, we’ll look at equivalent constructs that use logical operators or *if-else* statements.

## 2. Ternary Operator

**The ternary operator is a compact and efficient way to write conditional expressions**. It’s a shorthand way of writing an *if-else* statement that returns a value.

In Bash, the syntax for the ternary operator occurs inside double parentheses which allow for arithmetic evaluation:

`((condition ? value_if_true : value_if_false))`

We’ll refer to the three operands respectively as expressions *expr1*, *expr2*, and *expr3*:

`((expr1 ? expr2 : expr3))`

The expression *expr1* is first evaluated. **If the result in Boolean is non-zero (true), then the interpreter evaluates expression expr2**. Otherwise, it evaluates

*expr3*.

## 3. Finding the Maximum Among Two Integers

Suppose we want to find the maximum of two integers *a* and *b*. We can either use a ternary expression to do so or use an equivalent construct via an *if-else* statement or logical operators.

### 3.1. Using a Ternary Expression

First, let’s see how we can set *z* to the maximum of *a* and *b* via a ternary expression:

```
$ a=1; b=2
$ z=$((a > b ? a : b))
$ echo "$z"
2
```

Here, the interpreter evaluates the first operand and determines that it’s false since *a* (*1*) isn’t greater than *b* (*2*). Therefore, the returned value is the third operand, *b*, which has a value of 2.

Alternatively, we can set the variable *z* directly within the double parentheses:

```
$ ((z = a > b ? a : b))
$ echo "$z"
2
```

Instead of using double parentheses for arithmetic evaluation, we can also assign the result of a ternary expression to a variable using the *let* command:

```
$ let z="(a > b) ? a : b"
$ echo "$z"
2
```

Finally, it’s also possible to place the assignment inside the quotations:

```
$ let "z = (a > b) ? a : b"
$ echo "$z"
2
```

Moreover, ternary expressions can generally be rewritten as *if-else* statements or using logical operators.

### 3.2. Equivalent *if-else* Statement

Let’s rewrite the ternary expression as an *if-else* statement:

```
$ if [ "$a" -gt "$b" ]; then z="$a"; else z="$b"; fi
$ echo "$z"
2
```

We use square brackets to test an expression. The *-gt* option inside the brackets stands for *greater than*, i.e., we’re testing if the value of *a* is greater than *b*.

### 3.3. Equivalent Expression Using Logical Operators

Alternatively, we can use logical operators *&&* and *||* to rewrite our expression:

```
$ z=$([ "$a" -gt "$b" ] && echo "$a" || echo "$b")
$ echo "$z"
2
```

The entire expression in this case runs in a subshell.

However, we can further shorten the expression:

```
$ [ "$a" -gt "$b" ] && z="$a" || z="$b"
$ echo "$z"
2
```

This way, we don’t need to spawn a subshell for the assignment.

## 4. Ternary Expressions and Arithmetic Evaluation

**It’s important to note that Bash’s ternary expressions are limited to arithmetic expressions only**. However, we can always find a workaround by adding a subsequent *if-else* statement:

```
$ cat script.sh
x=17
output=$((x % 2 == 0 ? 1 : 0))
if [ "$output" -eq 1 ]; then
echo 'The number is even'
else
echo 'The number is odd'
fi
```

In this example, we’re using the ternary operator in combination with the modulo operator, *%*, to test whether the value of the variable *x* is even or odd. If the remainder of *x* is zero when divided by *2*, the ternary operator returns the value *1*. Otherwise, it returns *0*.

Then, we use an *if-else* statement to check the value of *output* and print the appropriate message, which we wouldn’t be able to do with the ternary expression alone.

## 5. Nested Ternary Expressions

**It’s also possible to nest ternary expressions**. For example, we can construct a ternary expression to find the maximum among three integers *a*, *b*, and *c*:

```
$ a=1; b=2; c=3
$ echo $(( max = a > b ? ( a > c ? a : c) : (b > c ? b : c) ))
3
```

In this case, **the second and third operands or the main ternary expression are themselves ternary expressions**. If *a* is greater than *b*, then *a* is compared to *c* and the larger of the two is returned. Otherwise, *b* is compared to *c* and the larger is returned.

Numerically, since the first operand evaluates to zero (false), the interpreter evaluates the third operand and returns the value of *c* since *b* isn’t greater than *c*.

## 6. Order of Evaluation

**The ternary operator associates from right to left**:

`(( expr1 ? expr2 : expr3 ? expr4 : expr5 ))`

We can make the expression clearer by enclosing the third operand with single parentheses:

`(( expr1 ? expr2 : ( expr3 ? expr4 : expr5 ) ))`

The two expressions are equivalent, though the second is more readable than the first. **In cases where expressions could be misinterpreted, it’s good practice to highlight operands with parentheses for better readability**.

As an example, suppose we wish to compare two integers *a* and *b*. If *a* is larger than *b*, then *a* is returned, otherwise, the larger of integers *b* and *c* is returned:

```
$ a=1; b=2; c=3
$ echo $((a > b ? a : b > c ? b : c))
3
```

Since ternary expressions associate from right to left, we can highlight this fact:

```
(( a > b ? a : ( b > c ? b : c ) ))
(( 1 > 2 ? 1 : ( 2 > 3 ? 2 : 3 ) ))
----- --- ---------------
expr1 expr2 expr3
```

Since *expr1* is false, *expr3* is evaluated and the result is the value of *c*.

## 7. Conclusion

In this article, we’ve seen that conditional operators can simplify code and make it more compact. If used wisely, conditional operators can also make code easier to read and understand. We’ve also seen that we can construct equivalent expressions using *if-else* statements or logical operators.