Bash arithmetic operations

Arithmetic expression

The syntax of ((...)) can perform arithmetic operations on integers.

\$ ((foo = 5 + 5))
\$ echo \$foo
10

((...)) will automatically ignore the internal spaces, so the following writing methods are correct and get the same result.

\$ ((2+2))
\$ (( 2+2 ))
\$ (( 2 + 2 ))

This syntax does not return a value, and the result of the command execution depends on the result of the arithmetic operation. As long as the arithmetic result is not 0, the command is executed successfully.

\$ (( 3 + 2 ))
\$ echo \$?
0

In the above example, the result of 3 + 2 is 5. Even if the command is executed successfully, the environment variable \$? is 0.

If the arithmetic result is 0, the command will be considered as execution failure.

\$ (( 3-3 ))
\$ echo \$?
1

In the above example, the result of 3-3 is 0, and the environment variable \$? is 1, indicating that the command execution failed.

If you want to read the result of an arithmetic operation, you need to add a dollar sign \$((...)) in front of ((...)) to make it an arithmetic expression and return the value of the arithmetic operation.

\$ echo \$((2 + 2))
4

The arithmetic operators supported by the ((...)) syntax are as follows.

-+: addition --: Subtraction -*: multiplication -/: division (division) -%: remainder -**: Index -++: Increment operation (prefix or suffix) ---: subtraction operation (prefix or suffix)

Note that the return result of the division operator is always an integer, such as 5 divided by 2, the result is 2 instead of 2.5.

\$ echo \$((5 / 2))
2

The two operators ++ and -- have a prefix and suffix difference. As a prefix, it returns the value after the operation, and as a suffix, it returns the value before the operation.

\$ i=0
\$ echo \$i
0
\$ echo \$((i++))
0
\$ echo \$i
1
\$ echo \$((++i))
2
\$ echo \$i
2

In the above example, ++ as a suffix is ​​to return the value first, execute the echo command, and then perform the auto-increment operation; as a prefix, the auto-increment operation is performed first, and then the return value executes the echo command.

Parentheses can be used inside \$((...)) to change the order of operations.

\$ echo \$(( (2 + 3) * 4 ))
20

In the above example, the inner parentheses let the addition be performed before the multiplication.

\$((...)) structure can be nested.

\$ echo \$(((5**2) * 3))
75
# Equivalent to
\$ echo \$((\$((5**2)) * 3))
75

This syntax can only calculate integers, otherwise an error will be reported.

# Error
\$ echo \$((1.5 + 1))
bash: syntax error

In the parentheses of \$((...)), there is no need to add \$ before the variable name, but adding it will not report an error.

\$ number=2
\$ echo \$((\$number + 1))
3

In the above example, if there is a dollar sign in front of the variable number, the result is the same.

If you use a string in \$((...)), Bash will think that it is a variable name. If there is no variable with the same name, Bash will treat it as a null value, so no error will be reported.

\$ echo \$(( "hello" + 2))
2
\$ echo \$(( "hello" * 2))
0

In the above example, "hello" will be treated as a variable name and return a null value, and \$((...)) will treat a null value as 0, so the result of the multiplication operation is 0 . Similarly, if a variable that does not exist in \$((...)) is used, it will be treated as 0.

If the value of a variable is a string, the processing logic is the same as above. That is, if the string does not correspond to an existing variable, it will be treated as a null value in \$((...)).

\$ foo=hello
\$ echo \$(( foo + 2))
2

In the above example, the value of the variable foo is hello, and hello will also be regarded as the variable name. This makes it possible to write code that is dynamically replaced.

\$ foo=hello
\$ hello=3
\$ echo \$(( foo + 2 ))
5

In the above code, foo + 2 depends on the value of the variable hello.

Finally, \$[...] is the previous syntax, which can also do integer arithmetic and is not recommended.

\$ echo \$[2+2]
4

Numerical base

Bash values ​​are all decimal by default, but in arithmetic expressions, other bases can also be used.

-number: The number without any special notation is a decimal number (base 10). -0number: octal number. -0xnumber: Hexadecimal number. -base#number: The number in the base of base.

Here are some examples.

\$ echo \$((0xff))
255
\$ echo \$((2#11111111))
255

In the above example, 0xff is a hexadecimal number, and 2#11111111 is a binary number.

Bit operation

\$((...)) supports the following binary bit operators.

-<<: Bit shift operation to move all bits of a number to the left by a specified bit. ->>: Bit right shift operation, move all bits of a number to the right by the specified bits. -&: Bit "AND" operation, perform an AND operation on all the bits of two numbers. -|: bit "or" operation, performs an OR operation on all the bits of two numbers. -~: bit "no" operation, invert all the bits of a number. -^: Exclusive or operation of bits, which performs an exclusive or operation on all bits of two numbers.

The following is an example of the right shift operator >>.

\$ echo \$((16>>2))
4

The following is an example of the left shift operator <<.

\$ echo \$((16<<2))
64

Below are the results of various binary operations on 17 (binary 10001) and 3 (binary 11).

\$ echo \$((17&3))
1
\$ echo \$((17|3))
19
\$ echo \$((17^3))
18

logic operation

\$((...)) supports the following logical operators.

-<: less than ->: greater than -<=: less than or equal ->=: greater than or equal -==: equal -!=: Not equal -&&: logical AND -||: logical OR -!: logical no -expr1?expr2:expr3: ternary conditional operator. If the calculation result of the expression expr1 is non-zero (arithmetic true), the expression expr2 is executed, otherwise the expression expr3 is executed.

If the logical expression is true, return 1, otherwise return 0.

\$ echo \$((3> 2))
1
\$ echo \$(( (3> 2) || (4 <= 1) ))
1

The ternary operator performs a single logical test. It is used similar to the if/then/else statement.

\$ a=0
\$ echo \$((a<1? 1: 0))
1
\$ echo \$((a>1? 1: 0))
0

In the above example, when the first expression is true, the value of the second expression is returned, otherwise the value of the third expression is returned.

Assignment operation

Arithmetic expression \$((...)) can perform assignment operation.

\$ echo \$((a=1))
1
\$ echo \$a
1

In the above example, a=1 assigns a value to the variable a. This formula itself is also an expression, and the return value is the value on the right side of the equal sign.

The assignment operators supported by \$((...)) are as follows.

-parameter = value: simple assignment. -parameter += value: equivalent to parameter = parameter + value. -parameter -= value: equivalent to parameter = parameter – value. -parameter *= value: equivalent to parameter = parameter * value. -parameter /= value: equivalent to parameter = parameter / value. -parameter %= value: equivalent to parameter = parameter% value. -parameter <<= value: equivalent to parameter = parameter << value. -parameter >>= value: equivalent to parameter = parameter >> value. -parameter &= value: equivalent to parameter = parameter & value. -parameter |= value: equivalent to parameter = parameter | value. -parameter ^= value: equivalent to parameter = parameter ^ value.

Below is an example.

\$ foo=5
\$ echo \$((foo*=2))
10

If you assign a value inside the expression, you can put it in parentheses, otherwise an error will be reported.

\$ echo \$(( a<1? (a+=1): (a-=1) ))

Evaluation operation

The comma , is an evaluation operator inside \$((...)), executes the two expressions before and after, and returns the value of the latter expression.

\$ echo \$((foo = 1 + 2, 3 * 4))
12
\$ echo \$foo
3

In the above example, both expressions before and after the comma will be executed, and then return the value of the latter expression 12.

expr command

The expr command supports arithmetic operations, and the ((...)) syntax can be omitted.

\$ expr 3 + 2
5

The expr command supports variable substitution.

\$ foo=3
\$ expr \$foo + 2
5

The expr command also does not support non-integer parameters.

\$ expr 3.5 + 2
expr: non-integer parameter

In the above example, if there is a non-integer operation, the expr command will report an error.

let command

The let command is used to assign the result of an arithmetic operation to a variable.

\$ let x=2+3
\$ echo \$x
5

In the above example, the variable x is equal to the result of the operation of 2+3.

Note that there can be no spaces in the expression x=2+3, otherwise an error will be reported. The detailed usage of the let command can be found in the chapter "Variables".