Syntax error invalid arithmetic operator error token is

«invalid arithmetic operator» in shell then I modify the test.sh: /bin/bash -x test.sh why this error appears, any suggestion will be appreciate! 3 Answers 3 only appears to work. Since arr is an ordinary array, not an associative array, it can only be indexed by non-negative integer values. Consider this valid code: All the […]

Содержание

  1. «invalid arithmetic operator» in shell
  2. 3 Answers 3
  3. bash — syntax error invalid arithmetic operator error token is
  4. bash syntax error: invalid arithmetic operator with token «@mail.com»
  5. 2 Answers 2
  6. getting syntax error: invalid arithmetic operator (error token is «. «) #357
  7. Comments
  8. invalid arithmetic operator (error token is » «) with for loop
  9. 3 Answers 3
  10. Linked
  11. Related
  12. Hot Network Questions
  13. Subscribe to RSS

«invalid arithmetic operator» in shell

then I modify the test.sh:

/bin/bash -x test.sh

why this error appears, any suggestion will be appreciate!

3 Answers 3

only appears to work. Since arr is an ordinary array, not an associative array, it can only be indexed by non-negative integer values.

Consider this valid code:

All the echo statements print val . Since the index is treated as an arithmetic expression, it can refer to a variable (in this case, $index ) either with or without the $ prefix — even if it’s a quoted string.

In your code, where you never assigned a value to $index , $]> expands to $ , which is equivalent to $ , which is treated (by default) as equivalent to $ .

(If you have set -o nounset , then references to unset variables are treated as errors, and your code will produce an error message.)

Your second chunk of code:

is invalid because index.index is not a valid variable name — even though you probably meant it to be just a string used as an array index.

If you want arr to permit arbitrary strings as indices, it needs to be an associative array. You can create a non-associative array simply by assigning to it (or by using declare -a ), but an associative array can only be created with declare -A .

Associative arrays were added to bash in version 4. If you’re using an earlier version of bash, declare -A is not supported. You’ll need to upgrade to a newer bash, code up some clumsy alternative, or use a language that does support associative arrays, like Awk, Python, or Perl.

Adding declare -A arr (as user000001’s answer suggests) should solve the problem (if you have bash 4), but it’s instructive to understand what your original code is actually doing (or rather not doing).

(BTW, thanks for asking this; I learned a lot as I was composing this answer.)

Источник

bash — syntax error invalid arithmetic operator error token is

Приветствую! Ребята подскажите где я не догоняю?

Нужно выполнить проверку значений с первого массива во втором.

Элементы массива закавычь

Пробовал и ‘ кавычить и » кавычить. Одно и тоже.

Это из-за противоестественного интеллекта такое, если цифры — значить индекс, а не ассоциация. Добавьте везде букву при заполнении и сравнениях.

Жесть, а нет может ключа какого? что бы указал что здесь строка арифметика не нужна.

Добавил слово ip /usr/net/net-up: line 67: ip172.20.0.3/24: syntax error: invalid arithmetic operator (error token is «.20.0.3/24»)

Нате. Специально добавил несуществующий в конец current_ifip

На bash’e любой !Ъ сможет, даешь POSIX shell!

state_ip это не ассоциативный массив вообще-то, не смущает?

У вас тоже не bourne 🙂 Все эти $(cmd) $

. Если уж юзаете set —, то накой вообще этот load()? Делайте IFS=» » set —. Ну и т д.

А это башизм, да 🙂

Если уж юзаете set —, то накой вообще этот load()?

Чисто эстетически смотрится лучше, ИМХО. Сам смысл load() что бы построить подобие хеш-таблицы.

Этого не понял. Зачем IFS менять в данном случае ? .

Да это чисто новомодный эфемизм к обратным апострофам, мож и POSIX, но не такой уж и древний.

Для гарантии. Это правильный стиль, ибо меняет не глобально и самодокументированно для демонстрации чего хотят сделать в этой строчке.

Это правильный стиль, ибо меняет не глобально и самодокументированно для демонстрации чего хотят сделать в этой строчке.

Я понимаю, что он делает, и для чего нужен в целом. Я спрашивал за другое — чем или как именно замена IFS поможет конкретно в этом случае ? .

чем или как именно замена IFS поможет конкретно в этом случае

Сделает ровно то что вы делаете load() — распарсит строку по аргументам с разделителем пробел.

Почти то что нужно, но не совсем. Помогите доработать.

Первый раз ip добавляются второй раз прогоняю скрипт он снова пытается добавить. Т.е. не отрабатывает проверка в списке.

Источник

bash syntax error: invalid arithmetic operator with token «@mail.com»

I have a script that performs a SQL SELECT and sends some e-mails using the output but there is an issue with the script causing the error message:

line 34: johne@mail.com: syntax error: invalid arithmetic operator (error token is «@mail.com»)

Here is the script:

2 Answers 2

The problem is that you are trying to perform a string comparison inside an arithmetic expression. Either switch to a compound expression:

or check that you are accessing the correct element of msgData .

It first seemed to me that this is a limitation of the implementation of associative arrays in bash (as of v4.3.11 here).

Associative arrays are created using

Arrays are assigned to using compound assignments of the form

where each value is of the form [subscript]= string.

And then you look up subscript a few lines earlier:

The subscript is treated as an arithmetic expression that must evaluate to a number.

So it’s saying a string «foo@bar» can’t evaluate to a number, and can’t be used as an array key? But that doesn’t explain why strings without «@» can.

The confusing part is also that when you do the assignment manually, e.g.

That works fine. Bother.

The solution for this, as it turns out, is to repeat the declare -A part in the assignment, like this:

In the specific example above, it’s probable that $ gets evaluated in integer context because you use the comparison.

So I’d wager that you want to do something like quote it to escape that context first.

Or simply do it with fewer shorthands, without the :- modifier, which really contributes to the impression of line noise when combined with all the other punctuation on that line. For example:

Источник

getting syntax error: invalid arithmetic operator (error token is «. «) #357

This might not be a bash-completion issue, but I hope at least by explaining the issue that I could get some help debugging the issue.

The issue is this:

$ a.b bash: a.b: syntax error: invalid arithmetic operator (error token is «.b»)

If I source bash_completion like so:

everything works like expected:

In my .bashrc I have the following

I have also tried explicitly sourcing /usr/local/Cellar/bash-completion@2/2.8/share/bash-completion/bash_completion in my bashrc, but seems to have no effect. For some reason it only works when I do it in my shell.

The text was updated successfully, but these errors were encountered:

See «Troubleshooting» in README.md.

I’ve tried sourcing bash_completion also in my .bash_profile, also my .bash_profile only sources .bashrc so this should be ok.
I’ve tried to run the same commands with set +v and set +x , but not getting any more useful output.

Or was there any other sections in the Troubleshooting guide you would recommend?

To get a trace what’s happening when you hit tab, you should be running under e.g. set -x , not set +x (which turns it off).

Thanks. When running $ a.b [tab] now yields:

Ah, right, that’s fixed in commit a47bd37 which is included in 2.9.

. or probably not after all, actually. Anyway I’ll try to have a closer look soon.

I believe the error occurs when we try to access the _xspecs associative array to check if there’s a completion for a.b there. I can simulate the error for a non-associative array:

. but _xspecs is defined as an associative array, and I cannot reproduce with such one:

It’s like that in 2.8 too, so I have no more ideas at the moment.

I see. Like mentioned, this works when I explicitly source bash_completion again in my shell, even though I do it in my .bashrc as well — which sounds wierd. Any way to verify that the sourcing operation done in .bashrc was successful?

bash —norc gives you a «clean» shell, you can do set -x there and invoke the same commands your shell does when it starts up. I’d first triple check that what you manually source in your shell is the same bash_completion your rcfiles do.

The issue was resolved when I moved the sourcing of bash-completion out of a function inside my .bashrc . (https://unix.stackexchange.com/questions/151889/why-does-bashs-source-command-behave-differently-when-called-from-a-function)
Thank very much for help with debugging this. (edit: don’t think that issue had the same problem)

Not sure if this is something that could be detected and prevented, I’ll leave it up to you to decide.

Источник

invalid arithmetic operator (error token is » «) with for loop

gives error solution.sh: line 2: ((: c

I am using BASH. What is wrong with the for loop?

edit: I am working on the BASH hackerrank IDE and although this code is not directly related to the problem in this link, I am getting this error.

3 Answers 3

I’ve reproduced this error message by pressing Ctrl-E after 1. It looked like this:

So make sure you are not pressing some strange combination of keys before enter.

You need to add this line

at the top of solution.sh .

(if your bash is at a different location, do, in a terminal,

to determine its location)

@picasso13 just a wild guess cause it got me(and yield the same mysterious error when I tried to loop with array constructed from the input). There are 2 inputs on hackerRank(the first one is actually the size of the second). It solved my problem when I threw away the first and make sure my iteration was working on the list of numbers:

if you comment out my read ignore you’ll reproduce the issue.

Linked

Hot Network Questions

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.1.14.43159

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Last updated: 2022-07-16

Math and Arithmetic are often used in Bash scripting, especially when writing crontab reports, monitoring plugins, setting up scripts with dynamic configurations, or other automation tasks like showing a Raspberry PI CPU temperature. There is always some arithmetic calculation to be made.

This post covers how to do basic mathematical operations (elementary arithmetic like multiplication and addition) in Bash with integers or floating-point numbers.

TL;DR: x=3; y=$((x+2)); echo $y will print 5

Introduction to Integers and Floating-Points

Before we get into the details on how to do Math in Bash, remember that an integer is a whole number that is not a fraction or decimal and is anywhere from zero to positive or negative infinity. For example, 42, 36, and -12 are integers, while 3.14 and √2 are not. The set of integers includes all negative integers (whole numbers that has value less than zero), zero, and all positive integers (whole numbers that has value larger than zero). An integer and its opposite are the same distance from zero.

A floating-point number is a computing programming term to represent a real number with a fractional part. For example 3.14, √2, -10.5, 4e-2 are floating points numbers. A floating-point is specified by a base (binary or decimal), a precision, and an exponent range. It is usually in binary made of 32 (simple precision) or 64 bits (double precision), thought the
IEEE 754 standard mention more formats.

Format Total bits Significand bits Exponent bits Smallest number Largest number
Single precision 32 23 + 1 sign 8 ≈ 1.2 ⋅ 10-38 ≈ 3.4 ⋅ 1038
Double precision 64 52 + 1 sign 11 ≈ 2.2 ⋅ 10-308 ≈ 1.8 ⋅ 10308

You may see a floating-point being represented in the form of significand x base exponent. For example: 3.14 = 314 x 10-2

What are the Bash Arithmetic Operators?

The Bash shell has a large list of supported arithmetic operators to do math calculations. They work with the let, declare, and arithmetic expansion methods described further below in this post.

Arithmetic Operator Description
id++, id– variable post-increment, post-decrement
++id, –id variable pre-increment, pre-decrement
-, + unary minus, plus
!, ~ logical and bitwise negation
** exponentiation
*, /, % multiplication, division, remainder (modulo)
+, — addition, subtraction
«, » left and right bitwise shifts
<=, >=, <, > comparison
==, != equality, inequality
& bitwise AND
^ bitwise XOR
| bitwise OR
&& logical AND
|| logical OR
expression ? expression : expression conditional operator
=, *=, /=, %=, +=, -=, «=, »=, &=, ^=, |= assignment

Doing Math in Bash with Integer

Natively, Bash can only do integer arithmetic, if you need to do arithmetic operations that requires floating-point arithmetic, see the next section.

Using the expr command line

The legacy way to do math calculations with integer, and only integer, has been for a long time to use the expr command line. Though, this method can be slow as expr is a binary, not a shell builtin. It will fork a new process which is not ideal in a large for-loop. Also, the expr behavior may vary between systems depending on the implementation.

# Subtraction
[me@linux ~]$ expr 1 - 1
0
# Addition
[me@linux ~]$ expr 1 + 1
2
# Assign result to a variable
[me@linux ~]$ myvar=$(expr 1 + 1)
[me@linux ~]$ echo $myvar
2
# Addition with a variable
[me@linux ~]$ expr $myvar + 1
3
# Division
[me@linux ~]$ expr $myvar / 3
0
# Multiplication
[me@linux ~]$ expr $myvar * 3
6

⚠️ When doing a multiply by make sure to escape the asterisk (*), or any other bash wildcards, to prevent pattern expansion in Bash. You can escape a special character using the backslash (), example: expr $myvar * 3. Not escaping the * would lead to an expr: syntax error.

Using the let or declare shell builtin commands

An alternative to the legacy expr command, is to use the Bash builtin command let or declare to evaluate Arithmetic Expressions. The declare builtin method require the -i option to do an Integer Declaration.

[me@linux ~]$ myvar=6 ; echo $myvar
6
[me@linux ~]$ let myvar+=1 ; echo $myvar
7
[me@linux ~]$ let myvar+1 ; echo $myvar
8
[me@linux ~]$ let myvar2=myvar+1 ; echo $myvar2
9

With both methods, you can combine multiple expressions on a single line as let and declare evaluate each argument as a separate arithmetic expression.

[me@linux ~]$ let x=4 y=5 z=x*y u=z/2
[me@linux ~]$ echo $x $y $z $u
4 5 20 10

[me@linux ~]$ declare -i x=4 y=5 z=x*y u=z/2
[me@linux ~]$ echo $x $y $z $u
4 5 20 10

⚠️ Integer Declaration using the declare -i notation can lead to confusing or hard-to-read shell scripts. A variable set as an integer may accept non-integer values, but it won’t store and output the expected new string and may error out. Using declare -i force a variable to be an arithmetic context only. It is like prefixing the variable assignment with the let command every time. Instead, it is generally clearer to use the Bash Arithmetic Expansion as detailed in the next section.

[me@linux ~]$ declare -i myvar3=myvar2*2 ; echo $myvar3
18
[me@linux ~]$ echo $myvar3 ; myvar3="none"; echo $myvar3
18
0

Using the Bash Arithmetic Expansion

The recommended way to evaluate arithmetic expressions with integers in Bash is to use the Arithmetic Expansion capability of the shell. The builtin shell expansion allows you to use the parentheses ((...)) to do math calculations.

The format for the Bash arithmetic expansion is $(( arithmetic expression )). The shell expansion will return the result of the latest expression given.

The $((...)) notation is what is called the Arithmetic Expansion while the ((...)) notation is called a compound command used to evaluate an arithmetic expression in Bash.

The Arithmetic Expansion notation should be the preferred way unless doing an arithmetic evaluation in a
Bash if statement, in a
Bash for loop, or similar statements.

👉 The square brackets $[...] can also do Arithmetic Expansion in Bash, though this notation has been deprecated and should be avoided. Instead, prefer the use of $((...)) instead.

[me@linux ~]$ myvar=3 && echo $myvar
3
[me@linux ~]$ echo $((myvar+2))
5
[me@linux ~]$ myvar=$((myvar+3))
[me@linux ~]$ echo $myvar
6
[me@linux ~]$ ((myvar+=3))
[me@linux ~]$ echo $myvar
9

This allows you to use C-style programming and easily increment or decrement a variable in Bash using the ++ or -- arithmetic operators. All the operators listed in the table above are fully available when using Arithmetic Expansion.

[me@linux ~]$ myvar=3 && echo $myvar
3
[me@linux ~]$ echo $((myvar++))
3
[me@linux ~]$ echo $myvar
4
[me@linux ~]$ echo $((++myvar))
5
[me@linux ~]$ echo $myvar
5

In the previous section, we show an example with let containing multiple expressions on a single line. This is also possible with Arithmetic Expansion. The only difference is that multiple expressions must be separated by a comma (,).

[me@linux ~]$ echo $((x=4,y=5,z=x*y,u=z/2))
10
[me@linux ~]$ echo $x $y $z $u
4 5 20 10

[me@linux ~]$ ((x=4,y=5,z=x*y,u=z/2)) ; echo $x $y $z $u
4 5 20 10

Doing Floating-point Arithmetic in Bash

Using the printf builtin command

A noteworthy but unconventional way to do floating-point arithmetic in native bash is to combine Arithmetic Expansion with printf using the scientific notation. Since you can’t do floating-point in bash, you would just apply a given multiplier by a power of 10 to your math operation inside an Arithmetic Expansion, then use printf to display the float.

For example, the operation 2/3 in Artithmetic Expansion as $((2/3)) would return 0. To get the floating number using printf you would use a formula like below where <precision> would be the floating-point precision to display and <multiplier> the power of ten multipliers. Similarly, a multiplier of 3 would mean 10**3, which is 1000.

printf %.<precision>f "$((10**<multiplier> * 2/3))e-<multiplier>

Note that the floating point precision in %.<precision>f shouldn’t be higher than the multiplier itself as it will just fill with zeros.

[me@linux ~]$ printf %.3f "$((10**3 * 2/3))e-3"
0.666
[me@linux ~]$ printf %.1f "$((10**3 * 2/3))e-3"
0.7
[me@linux ~]$ printf %.5f "$((10**3 * 2/3))e-3"
0.66600

Using the awk command line

Another way to do floating-point arithmetic is to use GNU awk. You can use all the arithmetic operators listed in the table earlier in this post and the printf function to adjust the precision of the printed results.

[me@linux ~]$ awk "BEGIN {print 100/3}"
33.3333
[me@linux ~]$ awk "BEGIN {x=100/3; y=6; z=x*y; print z}"
200
[me@linux ~]$ awk "BEGIN {printf "%.2fn", 100/3}"
33.33

When using negative values, make sure to leave white space between signs.

[me@linux ~]$ awk "BEGIN {print -8.4--8}"
awk: cmd. line:1: BEGIN {print -8.4--8}
awk: cmd. line:1:                    ^ syntax error
[me@linux ~]$ awk "BEGIN {print -8.4 - -8}"
-0.4

Using the bc command line

Since you can’t do floating-point arithmetic natively in Bash, you will have to use a command-line tool. The most common one is “
bc — An arbitrary precision calculator language
”.

To start the interactive mode, you simply need to type bc in your command prompt. You can use the -q (quiet) option to remove the initial bc banner.

[me@linux ~]$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
3*5.2+7/8
15.6
15.6+299.33*2.3/7.4
108.6

Of course, you can also use bc in a non-interactive mode by using the STDIN to send your formula to bc then get the output on STDOUT, or by using the
here-doc notation.

# Example of piped arithmetic expression to the bc STDIN
[me@linux ~]$ echo "15.6+299.33*2.3/7.4" | bc
108.6

# Example using the here-doc notation
[me@linux ~]$ bc <<< "15.6+299.33*2.3/7.4" 
108.6

There are four special variables, scale, ibase, obase, and lastscale defines how some operations use digits after the decimal point.  The default value of scale is 0. ibase and obase define the conversion base for input and output numbers.  The default for both input and output is base 10. last (an extension) is a variable that has the value of the last printed number.

The “scale” variable is essential for the precision of your results, especially when using integers only.

👉 Note: you can also use bc -l to use mathlib and see the result at max scale.

[me@linux ~]$ echo "2/3" | bc
0
[me@linux ~]$ echo "scale=2; 2/3" | bc
.66
[me@linux ~]$ echo "(2/3)+(7/8)" | bc
0
[me@linux ~]$ echo "scale=2;(2/3)+(7/8)" | bc
1.53
[me@linux ~]$ echo "scale=4;(2/3)+(7/8)" | bc
1.5416
[me@linux ~]$ echo "scale=6;(2/3)+(7/8)" | bc
1.541666
[me@linux ~]$ echo "(2/3)+(7/8)" | bc -l
1.54166666666666666666

👉 If you want to go further with bc, read my post on
Advanced Math Calculation using bc with an example on how to write a simple arithmetic calculator or to find the factorial of a number.

Detailed Examples & FAQ

How to calculate a percentage in Bash?

You can calculate a floating-point precision percentage in Bash using the printf method and Arithmetic Expansion, or you can calculate a rounded integer percentage using Arithmetic Expansion with the ((...)) notation.

The round-up approach leverages the shell behavior to round toward zero (0). We first calculate twice the percentage then subtract the regular percentage from it. This gives us the formula: roundup = (int) (2 * x) - (int) x where x is the percentage calculation.

[me@linux ~]$ fileProcessed=17; fileTotal=96;

# Floating-point precision using builtin printf method and Arithmetic Expansion
[me@linux ~]$ printf %.2f%% "$((10**3 * 100 * $fileProcessed/$fileTotal))e-3"
17.71%

# Rounding Up Using Arithmetic Expansion and Integers only
[me@linux ~]$ echo $((200 * $fileProcessed/$fileTotal))
35
[me@linux ~]$ echo $((100 * $fileProcessed/$fileTotal ))
17
[me@linux ~]$ echo $((200 * $fileProcessed/$fileTotal -  100 * $fileProcessed/$fileTotal ))%
18%

How to find a factorial in a shell script?

To calculate the factorial of a number in Bash or any POSIX shell, you can use the Arithmetic Expansion and a recursive function. The factorial function symbol in mathematic is ! and a factorial is defined by the formula n! = (n-1)! * n.

[me@linux ~]$ function f() {
  local x=$1
  if ((x<=1)); then
     echo 1
  else
     n=$(f $((x-1)))
     echo $((n*x))
  fi
}
[me@linux ~]$ f 1
1
[me@linux ~]$ f 2
2
[me@linux ~]$ f 3
6
[me@linux ~]$ f 6
720
[me@linux ~]$ f 8
40320

⚠️ This solution is limited to the maximum value of a numeric shell variable in your environment. You can try to resolve the following arithmetic expression echo $((2**64)). If the result is zero, your platform and shell environment won’t support beyond the 20 factorial. Trying to resolve a larger number factorial with this method would lead to inaccurate results. Therefore, you should prefer using bc for reliable results without such constraints. For an example of a recursive factorial function using bc see
How to find factorial of a number in a shell script using bc?.

How to create a simple bash calculator function?

As a thought experiment, you can create a calculator command to do math by using a
bash function, a bash arithmetic expression, and a bash variable inference. Every time the calculator function is called, it will update a variable name by a given value or by default 1 with a given arithmetic operator. Example: counter <var_name> <operator> <value>. You can also implement an interactive version of a
simple calculator by using bc.

[me@linux ~]$ A=0; B=0;
[me@linux ~]$ calculator() ((${1}=${!1}${3:-+}${2:-1}))
[me@linux ~]$ echo "Counter A=$A and B=$B"
Counter A=0 and B=0
[me@linux ~]$ calculator A; calculator B
[me@linux ~]$ echo "Counter A=$A and B=$B"
Counter A=1 and B=1
[me@linux ~]$ calculator A 5; calculator B 2
[me@linux ~]$ echo "Counter A=$A and B=$B"
Counter A=6 and B=3
[me@linux ~]$ calculator A 5 /; calculator B 2 "*"
Counter A=1 and B=6

Obviously, this example is just to demonstrate some of the concepts to do math while using other bash constructs. For a simple variable assignment, you should prefer to use the assignments
bash arithmetic operators.

How to do math on a date using Arithmetic Expansion and printf?

Below is a simple example of doing a date manipulation with a math subtraction in shell script by using the new $EPOCHSECONDS variable from
GNU Bash version 5 and printf date formatting. The example shows the current time minus 86400 seconds.

[me@linux ~]$ echo $EPOCHSECONDS
1589153003
[me@linux ~]$ printf 'Current day of the month is the %(%d)Tn' $EPOCHSECONDS
Current day of the month is the 10
[me@linux ~]$ printf 'Previous day of the month was the %(%d)Tn' $((EPOCHSECONDS-86400))
Previous day of the month was the 09

👉 Read more on how to manipulate and format dates in bash in the post
How To Format Date and Time in Linux, macOS, and Bash?.

How to use different arithmetic bases in an Arithmetic Expansion?

With the Bash Arithmetic Expansion, you can perform calculations between different arithmetic bases. For example, add a base 10 integer to a base 2 integer. To do so, you can prefix each number with the base identifier and the hashtag character #, using the form base#number. The base must be a decimal between 2 and 64 representing the arithmetic base. The default base value used in bash arithmetic expansion is the base 10.

Note that, you can also prefix numbers with a leading zero 0 to represent octal numbers (base 8). A leading 0x or 0X would be interpreted as an hexadecimal. Also, the dollar sign $ is required in front of a variable when specifying a base identifier

[me@linux ~]$ echo $(( 10#2 + 2#1 ))
3
[me@linux ~]$ echo $(( 2 + 2#1 ))
3
[me@linux ~]$ echo $(( 10#2 + 16#aa ))
172
[me@linux ~]$ echo $(( 010 + 16#aa ))
178
[me@linux ~]$ echo $(( 0x10 + 16#aa ))
186
[me@linux ~]$ x=2 ; y=1a ; echo $(( x * 16#$y ))
52

⚠️ Using a base identifier only works with unsigned integers. There is a trick to workaround the issue and move the sign in front of the base identifier, see example below. In general, when doing complex math calculation, you should prefer another solution like using the
Linux bc command line.

[me@linux ~]$ x=-08 ; echo $(( 10#$x ))
bash: -08: value too great for base (error token is "08")
[me@linux ~]$ echo $(( ${x%%[!+-]*}10#${x#[-+]} ));
-8

How to solve the bash error value too great for base (error token is…?

As mentioned above, Bash Arithmetic Expression will automatically consider numbers with leading zero as octal numbers (base 8). When a variable is expended to represent a number with leading zeros and composed with numbers equal or above 8, it will lead to a bash arithmetic error like bash: 08: value too great for base (error token is "08").

[me@linux ~]$ x=01 ; echo $((x+1))
2
[me@linux ~]$ x=0105 ; echo $((x+1))
70
[me@linux ~]$ x=08 ; echo $((x+1))
bash: 08: value too great for base (error token is "08")

To prevent such issues, you must remove the leading zeroes on the variable before doing the Arithmetic Expansion. This can be easily done with the
Bash wildcards and the extended globbing patterns.

Though, a simpler solution may be to ensure the variable is using a base identifier for the base 10 instead of the default representation (see question above). You must use the dollar sign $ in front of a variable when using the base identifier notation.

# Example using extended glob
[me@linux ~]$ shopt -s extglob
[me@linux ~]$ x=08 ; x=${x##+(0)}; echo $((x+1))
9

# Example using a base 10 identifier
[me@linux ~]$ x=08 ; echo $((10#$x+1))
9

If you are getting this error when using signed numbers, then refer to the previous question as the base identifier only works with unsigned numbers.

How to solve the syntax error: invalid arithmetic operator?

When using Arithmetic Expansion, you may encounter the following error:

syntax error: invalid arithmetic operator (error token is ...)

This error is generally due to improperly formatted variables or integers used in the arithmetic expression. The most common mistake would be to try to use a floating-point number, which would fail as such.

[me@linux ~]$ echo "$((20.0+7))"
-bash: 20.0/7: syntax error: invalid arithmetic operator (error token is ".0+7")

Another mistake would be assigning a value to a variable with hidden characters and then using that variable in the arithmetic expansion.

[me@linux ~]$ a=$' 3r'
[me@linux ~]$ echo "$((a+7))"
")syntax error: invalid arithmetic operator (error token is "

You will notice that in such cases, the error message even gets mangled due to the carriage return character r in the variable. To prevent such issues, you will want to ensure the variables you use are properly formatted by stripping out control characters, mainly those with ASCII values from 1 (octal 001) to 31 (octal 037). You can do that by using the
shell parameter expansion.

[me@linux ~]$ echo "$((${a//[ $'01'-$'37']}+7))"
10

👉 Before Bash version 5, you may need to ensure the right collating order of the ASCII values by using shopt -s globasciiranges. Though, since Bash version 5, you don’t need to worry about the globasciiranges option since it is now set by default. Read more about Bash 5 with the post
What’s New in GNU Bash 5?

How to solve the bash error integer expression expected?

When using the test or single square bracket [ commands with a
conditional expression, you may encounter the error integer expression expected. This error will occur when you try to make an arithmetic comparison on strings, i.e., not whole numbers. It is similar to the invalid arithmetic operator error when using the double square brackets [[ as mentioned above. Make sure the variable you use is free of invalid characters; see the previous question on
invalid arithmetic operator.

Note that it is best practice to use the bash arithmetic compound expression with actual arithmetic operators instead of the legacy -lt, -gt, -le, and -ge.

# ERROR
[me@linux ~]$ [ 1 -lt 4.0 ] && echo "1 is smaller than 4.0"
bash: [: 4.0: integer expression expected

# CORRECT
[me@linux ~]$ [ 1 -lt 4 ] && echo "1 is smaller than 4"
1 is smaller than 4

# BEST
[me@linux ~]$ ((1<4)) && echo "1 is smaller than 4"
1 is smaller than 4

Introduction

Math and arithmetic operations are essential in Bash scripting. Various automation tasks require basic arithmetic operations, such as converting the CPU temperature to Fahrenheit. Implementing math operations in Bash is simple and very easy to learn.

This guide teaches you how to do basic math in Bash in various ways.

bash math bash arithmetic explained

Prerequisites

  • Access to the command line/terminal.
  • A text editor to code examples, such as nano or Vi/Vim.
  • Basic knowledge of Bash scripting.

Why Do You Need Math in Bash Scripting?

Although math is not the primary purpose of Bash scripting, knowing how to do essential calculations is helpful for various use cases.

Common use cases include:

  • Adding/subtracting/multiplying/dividing numbers.
  • Rounding numbers.
  • Incrementing and decrementing numbers.
  • Converting units.
  • Floating-point calculations.
  • Finding percentages.
  • Working with different number bases (binary, octal, or hexadecimal).

Depending on the automation task, basic math and arithmetic in Bash scripting help perform a quick calculation, yielding immediate results in the desired format.

Bash Math Commands and Methods

Some Linux commands allow performing basic and advanced calculations immediately. This section shows basic math examples with each method.

Arithmetic Expansion

The preferable way to do math in Bash is to use shell arithmetic expansion. The built-in capability evaluates math expressions and returns the result. The syntax for arithmetic expansions is:

$((expression))

The syntax consists of:

  • Compound notation (()) which evaluates the expression.
  • The variable operator $ to store the result.

Note: The square bracket notation ( $[expression] ) also evaluates an arithmetic expression, and should be avoided since it is deprecated.

For example, add two numbers and echo the result:

echo $((2+3))
bash arithmetic expansion addition terminal output

The arithmetic expansion notation is the preferred method when working with Bash scripts. The notation is often seen together with if statements and for loops in Bash.

awk Command

The awk command acts as a selector for pattern expressions. For example, to perform addition using the awk command, use the following example statement:

awk 'BEGIN { x = 2; y = 3; print "x + y = "(x+y) }'
awk addition terminal output

For variables x = 2 and y = 3, the output prints x + y = 5 to the console.

bc Command

The bc command (short for basic calculator) is a command-line utility that renders the bc language. The program runs as an interactive program or takes standard input to perform arbitrary precision arithmetic.

Pipe an equation from standard input into the command to fetch results. For example:

echo "2+3" | bc
bc addition terminal output

The output prints the calculation result.

dc Command

The dc command (short for desk calculator) is a calculator utility that supports reverse Polish notation. The program takes standard input and supports unlimited precision arithmetic.

Pipe a standard input equation into the command to fetch the result. For example:

echo "2 3 + p" | dc
dc addition terminal output

The p in the equation sends the print signal to the dc command.

declare Command

The Bash declare command allows integer calculations. To use declare for calculations, add the -i option. For example:

declare -i x=2 y=3 z=x+y

Echo each variable to see the results:

echo $x + $y = $z
declare addition terminal output

The output prints each variable to the console.

expr Command

The expr command is a legacy command line utility for evaluating integer arithmetic. An example expr command looks like the following:

expr 2 + 3
expr addition terminal output

Separate numbers and the operation sign with spaces and run the command to see the calculation result.

factor Command

The factor command is a command-line utility that prints the factors for any positive integer, and the result factorizes into prime numbers.

For example, to print the factors of the number 100, run:

factor 100
factor 100 terminal output

The output prints the factored number.

let Command

The Bash let command performs various arithmetic, bitwise and logical operations. The built-in command works only with integers. The following example demonstrates the let command syntax:

let x=2+3 | echo $x
let addition terminal output

The output prints the results.

test Command

The test command in Linux evaluates conditional expressions and often pairs with the Bash if statement. There are two variations for the test syntax:

test 2 -gt 3; echo $?
test comparison terminal output

Or alternatively:

[ 2 -gt 3 ]; echo $?
test bracket comparison terminal output

The test command evaluates whether two is greater than (-gt) three. If the expression is true, the output is zero (0), or one (1) if false.

Bash Arithmetic Operators

Bash offers a wide range of arithmetic operators for various calculations and evaluations. The operators work with the let, declare, and arithmetic expansion.

Below is a quick reference table that describes Bash arithmetic operators and their functionality.

Syntax Description
++x, x++ Pre and post-increment.
--x, x-- Pre and post-decrement.
+, -, *, / Addition, subtraction, multiplication, division.
%, ** (or ^) Modulo (remainder) and exponentiation.
&&, ||, ! Logical AND, OR, and negation.
&, |, ^, ~ Bitwise AND, OR, XOR, and negation.
<=, <, >, => Less than or equal to, less than, greater than, and greater than or equal to comparison operators.
==, != Equality and inequality comparison operators.
= Assignment operator. Combines with other arithmetic operators.

How to Do Math in Bash

Bash offers different ways to perform math calculations depending on the type of problem.

Below are examples of some common problems which use Bash math functionalities or commands as a solution. Most examples use the Bash arithmetic expansion notation. The section also covers common Bash math errors and how to resolve them.

Math with Integers

The arithmetic expansion notation is the simplest to use and manipulate with when working with integers. For example, create an expression with variables and calculate the result immediately:

echo $((x=2, y=3, x+y))
bash arithmetic expansion variables terminal output

To evaluate multiple expressions, use compound notation, store each calculation in a variable, and echo the result. For example:

((x=2, y=3, a=x+y, b=x*y, c=x**y)); echo $a, $b, $c
bash multiple equations terminal output

When trying to divide, keep the following in mind:

1. Division by zero (0) is impossible and throws an error.

bash division by zero error terminal output

2. Bash arithmetic expansion does not support floating-point arithmetic. When attempting to divide in this case, the output shows zero (0).

non-integer result terminal output

The result of integer division must be an integer.

Incrementing and Decrementing

Bash arithmetic expansion uses C-style integer incrementing and decrementing. The operator for incrementing or decrementing is either before or after the variable, yielding different behavior.

If the operator is before the variable (++x or --x), the increment or decrement happens before value assignment. To see how pre-incrementing works, run the following lines:

number=1
echo $((++number))
c-style pre-increment terminal output

The variable increments, and the new value is immediately available.

If the operator is after the variable (x++ or x--), the increment or decrement happens after value assignment. To see how post-incrementing works, run the following:

number=1
echo $((number++))
echo $number
c-style post-increment terminal output

The variable stays the same and increments in the following use.

Floating-point Arithmetic

Although Bash arithmetic expansion does not support floating-point arithmetic, there are other ways to perform such calculations. Below are four examples using commands or programming languages available on most Linux systems.

1. Using awk for up to 6 decimal places:

awk 'BEGIN { x = 2.3; y = 3.2; print "x * y = "(x * y) }'
awk bash floating point arithmetic terminal output

2. Using bc with the -l flag for up to 20 decimal places:

echo "2.3 * 3.2" | bc -l
bc -l floating point arithmetic terminal output

3. Using Perl for up to 20 decimal places:

perl -e 'print 2.3*3.2'
perl floating point arithmetic terminal output

Perl often comes preinstalled in Linux systems.

4. Using printf and arithmetic expansion to convert a fraction to a decimal:

printf %.<precision>f "$((10**<multiplier> * <fraction>))e-<multiplier>"

Precision dictates how many decimal places, whereas the multiplier is a power of ten. The number should be lower than the multiplier. Otherwise, the formula puts trailing zeros in the result.

For example, convert 1/3 to a decimal with precision two:

printf %.2f "$((10**3 * 1/3))e-3"
printf bash arithmetic expansion floating point terminal output

Avoid this method for precise calculations and use it only for a small number of decimal places.

Calculating a Percentage and Rounding

Below are two ways to calculate a percentage in Bash.

1. Use printf with arithmetic expansion.

printf %.2f "$((10**4 * part/total))e-4"%

For example, calculate what percent 40 is from 71:

printf %.2f%% "$((10**4 * 40/71))e-4"%
printf percent calculation terminal output

The precision is limited to two decimal places, and the answer always rounds down.

2. Use awk with printf for better precision:

awk 'BEGIN { printf "%.2f%%", (part/total*100) }'

For instance, calculate how many percent is 40 from 71 with:

awk 'BEGIN { printf "%.2f%%", (40/71*100) }'
awk percent calculation terminal output

The answer rounds up if the third decimal place is higher than five, providing better accuracy.

Finding a Factorial in the Shell

To calculate a factorial for any number, use a recursive Bash function.

For small numbers, Bash arithmetic expansion works well:

factorial () { 
    if (($1 > 1))
    then
        echo $(( $( factorial $(($1 - 1)) ) * $1 ))
    else

        echo 1
        return
    fi
}

To check the factorial for a number, use the following syntax:

factorial 5
bash arithmetic expansion factorial function terminal output

The method is slow and has limited precision (up to factorial 20).

For higher precision, faster results, and larger numbers, use the bc command. For example:

echo 'define factorial(x) {if (x>1){return x*factorial(x-1)};return 1}
 factorial(<number>)' | bc

Replace <number> with the factorial number to calculate. For example, to find the factorial of 50, use:

echo 'define factorial(x) {if (x>1){return x*factorial(x-1)};return 1} factorial(50)' | bc
bc factorial function terminal output

The output prints the calculation result to the terminal.

Creating a Bash Calculator Function

Create a simple Bash calculator function with the following code:

calculate() { printf "%sn" "[email protected]" | bc -l; }
calculate bc function terminal output

The function takes user input and pipes the equation into the bc command.

Alternatively, to avoid using programs, use Bash arithmetic expansion in a function:

calculate() { echo $(("[email protected]")); }
calculate bash arithmetic expansion function terminal output

Keep the arithmetic expansion limitations in mind. Floating-point arithmetic is not available with this function.

Save the function into the .bashrc file to always have the function available in the shell.

Using Different Arithmetic Bases

By default, Bash arithmetic expansion uses base ten numbers. To change the number base, use the following format:

base#number

Where base is any integer between two and 64.

For example, to do a binary (base 2) calculation, use:

echo $((2#1010+2#1010))
bash binary math terminal output

Octal (base 8) calculations use a 0 prefix as an alias. For example:

echo $((010+010))
bash octal math terminal output

Hexadecimal (base 16) calculations allow using 0x as a base prefix. For example:

echo $((0xA+0xA))
bash hexadecimal math terminal output

The output prints the result in base ten for any calculation.

Convert Units

Create a simple Bash script to convert units:

1. Open a text editor, such as Vim, and create a convert.sh script. For example:

vim convert.sh

2. Paste the following code:

#!/bin/bash

## Program for feet and inches conversion

echo "Enter a number to be converted:"

read number

echo $number feet to inches:
echo "$number*12" | bc -l

echo $number inches to feet:
echo "$number/12" | bc -l

The program uses Bash read to take user input and calculates the conversion from feet to inches and from inches to feet.

3. Save the script and close:

:wq

4. Run the Bash script with:

. convert.sh
convert.sh bash script terminal output

Enter a number and see the result. For different conversions, use appropriate conversion formulas.

Solving «bash error: value too great for base»

When working with different number bases, stay within the number base limits. For example, binary numbers use 0 and 1 to define numbers:

echo $((2#2+2#2))

Attempting to use 2#2 as a number outputs an error:

bash: 2#2: value too great for base (error token is "2#2")
bash value too great for base error terminal

The number is not the correct format for binary use. To resolve the error, convert the number to binary to perform the calculation correctly:

echo $((2#10+2#10))

The binary number 10 is 2 in base ten.

Solving «syntax error: invalid arithmetic operator»

The Bash arithmetic expansion notation only works for integer calculations. Attempt to add two floating-point numbers, for example:

echo $((2.1+2.1))

The command prints an error:

bash: 2.1+2.1: syntax error: invalid arithmetic operator (error token is ".1+2.1")
bash syntax error invalid arithmetic operator terminal output

To resolve the error, use regular integer arithmetic or a different method to calculate the equation.

Solving «bash error: integer expression expected»

When comparing two numbers, the test command requires integers. For example, try the following command:

[ 1 -gt 1.5 ]

The output prints an error:

bash: [: 1.5: integer expression expected
bash integer expression expected error terminal

Resolve the error by comparing integer values.

Conclusion

You know how to do Bash arithmetic and various calculations through Bash scripting.

For more advanced scientific calculations, use Python together with SciPy, NumPy, and other libraries.

Понравилась статья? Поделить с друзьями:
  • Syntax error unexpected t logical or
  • Syntax error insert variabledeclarators to complete localvariabledeclaration
  • Syntax error unexpected t boolean or
  • Syntax error unexpected symbol expecting register
  • Syntax error unexpected string at end of statement