2

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?

rojomoke
  • 3,765
  • 2
  • 21
  • 30

4 Answers4

7

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.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
1

How about [ $(($x)) -lt $(($y)) ] or [[ $x -lt $y ]] ?

anishsane
  • 20,270
  • 5
  • 40
  • 73
1

Not a bug. The shell doesn't do arithmetic evaluation in conditional expressions. See the sections Arithmetic Expansion and ARITHMETIC EVALUATION in man bash for details about when arithmetic evaluation is done.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

Just recently ran into this at work. For the record, an assignment like x=10#012 doesn't evaluate the math expression unless the shell parameter (variable) has the "integer" attribute.

$ printf "%d\n" 012
10                  # this is what we're trying to avoid in this case
$ printf "%d\n" 10#012
-bash: printf: 10#012: invalid number
10

$ x=10#012          # string in...
$ echo $x
10#012              # ...string out

$ echo $((x))       # do arithmetic evaluation
12
$ x=$((x))          # do arithmetic evaluation, assign its string value back
$ echo $x
12

# turning the integer attribute on with 'declare'/'local' forces
# arithmetic evaluation right away
$ declare -i y=10#012
$ echo y
12
Ti Strga
  • 1,353
  • 18
  • 40