basharithmetic-expressions

Number Base in Bash


To force numbers to be interpreted in base10, you can prefix with 10#. Specifically 10#08 and 10#09 will be interpreted as valid decimal numbers, and not invalid octal numbers. (I'm taking the output of date +%S)

However, it seems I then can't use the variable in comparisons:

x=10#08
y=10#20
echo $((x+y))           // (returns 28, as expected)

while [ $x -lt $y ]
do
  x=$((x++))
done

gives me the error

-bash: [: 10#08: integer expression expected

Is this a bug in bash?


Solution

  • bash's [ builtin mostly emulates the old standard [ command (aka test, and yes it's really a command), which doesn't know about these newfangled base marks. But bash's arithmetic expressions ((( ))) and conditional expressions ([[ ]]) do:

    $ x=10#08
    $ y=10#20
    $ echo $((x+y))
    28
    $ [ $x -lt $y ] && echo yes
    -bash: [: 10#08: integer expression expected
    $ /bin/[ $x -lt $y ] && echo yes   # This uses external test cmd instead of builtin
    [: 10#08: bad number
    $ [[ $x -lt $y ]] && echo yes
    yes
    $ ((x<y)) && echo yes
    yes
    

    For purely arithmetic tests, (( )) is generally easiest to use. But both are bash extensions (i.e. not available in the brand-X shell), so be sure to start your script with #!/bin/bash, not #!/bin/sh.