Pergunta

I am executing the following piece of code. I am not sure why the calculation is happening in octal? How can I make this code better?

#!/bin/bash
gmthour=$(date -u +%H)
localhour=$(date +%H)
echo $gmthour
echo $localhour
tz=$(( gmthour - localhour ))
echo $tz

Error

22
08
MyFile.ksh: line 6: 08: value too great for base (error token is "08")
Foi útil?

Solução

The leading zero is what causes the number to be interpreted as octal. Quote from man bash:

ARITHMETIC EVALUATION
[...]
Constants with a leading 0 are interpreted as octal numbers. A leading 0x or 0X denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used.

Change the format string of the date commands to %k or %_H to get rid of leading zeroes:

#!/bin/bash
gmthour=$(date -u +%k)
localhour=$(date +%k)
echo $gmthour
echo $localhour
tz=$(( gmthour - localhour ))
echo $tz

Beware that your calculation will break when the day changes. Example:

$ date
Di 2. Jul 00:50:29 CEST 2013
$ gmthour=$(date -u +%k)
$ localhour=$(date +%k)
$ echo $gmthour
22
$ echo $localhour
0
$ echo $((gmthour - localhour))
22

CEST clearly isn't UTC+22.

Try this instead:

#!/bin/bash
gmthour=$(date -u +%k)
localhour=$(date +%k)
echo $gmthour
echo $localhour
if [ $(date +%w) -eq $(date -u +%w) ]; then
  tz=$(( gmthour - localhour ))
else
  tz=$(( 24 - gmthour + localhour ))
fi
echo $tz

Outras dicas

How about this?

tz=$(( 10#$gmthour - 10#$localhour ))

I am not sure why the calculation is happening in octal

Just because when there's a leading zero, the number is interpreted as being in radix 8. To prevent that, you can impose the shell to interpret number in radix 10 with 10#. But seeing your comment, let me stress that in this case you must explicitly use the dollar sign.

Hope this helps!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top