bashing octal numbers into decimal
The bash shell has a quirk in how it recognizes numbers that caused my monthly mail archiving cron job to hiccup again this morning. Numbers preceded by a zero are assumed to be octal. My script stores the previous month in a variable as follows:
MTH=$((`date +%m` - 1))
This worked fine until last month when I got the following error in the cron output: value too great for base (error token is “08″). Instead of storing the archive as 2005-07, it stored it as 2005-00. The date command as above returns the month as two digits which fools bash into thinking it is working with octal numbers for the first nine months of the year. August and September (08 and 09) are invalid values in octal.
The problem is fixed in one of two ways. GNU date can be told not to zero pad the numbers by inserting a hyphen between the ‘%’ and ‘m’:
MTH=$((`date +%-m` - 1))
The bash shell can also be told the number is decimal by using the base#number notation as follows:
MTH=$((10#`date +%m` - 1))
For September this modifies the date output to be 10#09, which bash evaluates as a decimal instead of octal 9. This method can be applied more generally to anytime a script is returning zero padded values that should be interpreted as decimal numbers.