Shell进制运算错误:08: value too great for base
发布于 2008-12-19 12:18 阅读:33,697 评论:0 标签: bash shell 进制

      昨天发现一个很奇怪的bug,一个分析log的程序,一个小时产生一个log文件,文件名中含有当时的小时数以作标识,其中小时为有前导零的24 小时格式。bug是第08和09小时的log为空,甚为诧异。

      分析程序后,定位于08和09这两个数字上。程序中有一步需要对小时数进行数学运算,问题就在于此,例如:

以下是代码片段:
[root@login yayu]# echo $((08 -2))
bash: 08: value too great for base (error token is "08")

      Google了一下找到了答案:原文点这![建议新窗口打开]

      原因:

以下是代码片段:
Numbers starting with leading 0 are Octal numbers  (base 8) in many programming
languages including C, Perl and shell. Valid octal digits are
0,1,2,3,4,5,6,7 so it barfs if it sees an 8 or a 9. You probably want
to work in straight numbers and make a leading 0 in your output
format with a sprintf("%02d") kind of formatting thing.
Anything starting with 0x or 0X is a hex number.

So the error message means exactly as it says- it's an error from
the let function complaining about the value being too big for the base.

Have fun,
Stuart.

      解决方案:

以下是代码片段:
You can explicitly state the base of a number using base#number
Code:
if [ $((10#$item)) -eq 0 ] ; then
That will have trouble if the number starts with a minus sign.
The '-' needs to be in front of the base like -10#009 for -9.

      原来是进制的问题,C, Perl 和 shell中以0开头的数字是八进制了,而在运算中也是严格如此,不会做自动转化,于是就报错了。如下解决:

以下是引用片段:
[root@login shengting]# echo $((10#08 -2))
6

      纠结问题的根源,还是我的shell写得太烂了......如果命令用得好就不会遇到这个bug了,不过写得好了,又怎么会在以后避免进制导致的问题呢?到底是先有鸡还是先有蛋呢?