126

Trying to figure out how to convert an argument to an integer to perform arithmetic on, and then print it out, say for addOne.sh:

echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
1
  • I try to format your question, but it remains somehow unclear. printf "1 + %s\n" $1 won't do ?
    – Archemar
    Sep 27 '15 at 19:50
144

In bash, one does not "convert an argument to an integer to perform arithmetic". In bash, variables are treated as integer or string depending on context.

To perform arithmetic, you should invoke the arithmetic expansion operator $((...)). For example:

$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3

or generally preferred:

$ echo "$((a + 1))"
3

You should be aware that bash (as opposed to ksh93, zsh or yash) only performs integer arithmetic. If you have floating point numbers (numbers with decimals), then there are other tools to assist. For example, use bc:

$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14

Or you can use a shell with floating point arithmetic support instead of bash:

zsh> echo $((3.14 + 1))
4.14
2
  • 3
    Using $(( )) or (( )) is unsafe if you don't know what the strings are (like user input). Consider this: foo=foo (( foo += 0 )) This will crash the script as it tries to recursively evaluate foo. Same with: foo=foo foo=$(( foo + 0 ))
    – art
    Aug 5 '16 at 2:00
  • 1
    This only works if you know that the variable holds a valid integer. I have lots of tests in my answer stackoverflow.com/a/59781257/117471 Jan 17 '20 at 5:02
22

Other way, you can use expr

Ex:

$ version="0002"
$ expr $version + 0
2
$ expr $version + 1
3
2
  • this crashed and died if I had characters after the number. I was trying to test battery percentage. when it got below 10, if always died because of the period. The solution below worked beautifully. Aug 1 '20 at 19:23
  • 2
    @EricSebasta "The solution below" - Don't forget that "above" and "below" have no meaning in SO because answers get moved around. Better to reference the specific user who helped you.
    – Lou
    Dec 3 '20 at 10:10
15

In bash, you can perform the converting from anything to integer using printf -v:

printf -v int '%d\n' "$1" 2>/dev/null

Floating number will be converted to integer, while anything are not look like a number will be converted to 0. Exponentiation will be truncated to the number before e

Example:

$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
1
  • 4
    In other shells without printf -v this can be achieved with command substitution: int="$(printf '%d' 123.123 2>/dev/null)" Apr 13 '18 at 19:11
13

A similar situation came up recently when developing bash scripts to run in both Linux and OSX environments. The result of one command in OSX returned a string containing the result code; i.e., " 0". Of course, this failed to test correctly in the following case:

if [[ $targetCnt != 0 ]]; then...

The solution was to force (i.e., 'convert') the result to an integer, similar to what @John1024 answered above so that it works as expected:

targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
1
  • 5
    == etc in [[ (also [ aka test) do string comparison. There are different operators for arithmetic comparison e.g. [[ $targetcnt -ne 0 ]]; see manpage (or info) under Conditional Expressions. To trim spaces specifically, you could use [ with unquoted variable expansion [ $targetcnt == 0 ] to get default wordsplitting (NOT done in [[) but in general that approach leads you into danger. Aug 5 '16 at 7:34
3

According to Bash documentation, the syntax for the evaluation of an arithmetic expression is $((expression)). For instance:

$ n=1
$ echo $((n+1))
2

You can use this in a script by assigning an argument to a variable, and then using arithmetic expansion:

n=$1
echo $((n+1))

Test it out:

$ bash ./test.sh 1
2
$ bash ./test.sh 7
8
0
1

Do not use $((n)) or similar (e.g., $((n + 0)) et al) if your number may have leading zero(es). Otherwise, your number will be treated as octal. See the following example:

n="057"
n=$((n + 0)
echo $n

Result:

47
New contributor
Tim is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.