2013-07-01 5 views
2

Я выполняю следующий фрагмент кода. Я не уверен, почему расчет происходит в восьмеричном? Как я могу сделать этот код лучше?Арифметическая ошибка - расчетная база как 8

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

Ошибка

22 
08 
MyFile.ksh: line 6: 08: value too great for base (error token is "08") 
+0

не может дублировать этот вопрос, какую версию баш? – michael501

+0

Шахта - bash-3.00. Я предполагаю, что вы получаете или не получаете проблему, зависящую от того, имеет ли localhour/gmthour лидирующий нуль или нет. – misguided

ответ

1

Начальный ноль - это то, что заставляет число интерпретироваться как восьмеричное. Цитата man bash:

ARITHMETIC ОЦЕНКА
[...]
Константы, начинающиеся с 0 интерпретируются как восьмеричные числа. Ведущий 0x или 0X обозначает шестнадцатеричный. В противном случае числа принимают форму [base #] n, где необязательная база представляет собой десятичное число от 2 до 64, представляющее арифметическую базу, а n - число в этой базе. Если база # опущена, то используется база 10.

Изменить формат строки из date команд %k или %_H, чтобы избавиться от ведущих нулей:

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

Помните, что ваш расчет будет перерыв при изменении день. Пример:

$ 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 явно не UTC + 22.

Попробуйте вместо этого:

#!/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 
+0

как это сломается. Можете ли вы подробно рассказать? – misguided

+0

Спасибо, что указали это – misguided

1

Как насчет этого?

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

Я не уверен, почему расчет происходит в восьмеричной

Просто потому, что, когда есть ведущий нуль, число интерпретируется как в поразрядной 8. Для того, чтобы предотвратить это, вы можете наложить оболочку на интерпретацию числа в радиусе 10 с помощью 10#. Но, увидев ваш комментарий, позвольте мне подчеркнуть, что в этом случае вы должны явно использовать знак доллара.

Надеюсь, это поможет!

+0

. Уже пробовав это сделать, получите 'MyFile.ksh: строка 6: 10 # gmthour: значение слишком велико для базы (маркер ошибки «10 # gmthour») ' – misguided

+1

@misguided Смотреть знаки доллара! –

+0

спасибо помощнику. Пропущенный знак доллара, как указано, при попытке кода. Значок Onc ethe снова включен. Проблема исправлена. – misguided