Help with script: DAYOFMONTH=$((`date -j '+%d'`)) fails on 9th of month

I have a shell script (/bin/sh) for backing up my subversion server in which I try to check the day of the month against a variable, but it fails on the 9th day of the month:

Code:
FORCE_BACKUP_ON_DAY=$((9))
FORCE_BACKUP="NO"

# ...

DAYOFMONTH=$((`date -j '+%d'`))

[ ${DAYOFMONTH} -eq ${FORCE_BACKUP_ON_DAY} ] && FORCE_BACKUP="YES"

It failed today when assigning to DAYOFMONTH since today's date is the ninth of February.
Code:
# echo `date -j '+%d'`
09

sh(1) seems tells me under Arithmetic Expansion that octal constants start with 0, and I am supposing 09 doesn't compute.

I guess I could use string variables rather than arithmetic, but is there another way to solve this problem? Thanks.

- Thomas Backman
 
What's with all the extra () everywhere?

The big problem is that you are comparing a zero-leading number (09) to a non-zero-leading number (9). The zero-leading number is being interpreted as octal, which is why it works for the first 8 days (08 == 8).

Either configure date to output non-zero-leading numbers ("+%e"), or don't compare bare numbers (add "" around variables).

The following works:
Code:
FORCE_BACKUP_ON_DAY="09"
FORCE_BACKUP="NO"

DAYOFMONTH=$( date "+%d" )

[ "${DAYOFMONTH}" -eq "${FORCE_BACKUP_ON_DAY}" ] && FORCE_BACKUP="YES"
 
the $(( )) comes from a rather literal reading of the man page of sh.

I was curious why this problem didn't occur on my production server, and so I tried the arithmetic assignment on that machine (8.2-RELEASE, updated with freebsd-update), and under fbsd FreeBSD 8.2 the assignment works even if it has a leading zero. $( 09 ) will result in 9.

FreeBSD 8.2 amd64: (/bin/sh)

Code:
export TEST=$(( 09 ))
echo ${TEST}
9

FreeBSD 9.0 amd64: (/bin/sh)

Code:
export TEST=$(( 09 ))
arithmetic expression: expecting EOF: "09"

I'm not saying there's anything wrong, it's just that it was unexpected. But thanks for the suggestion of using %e rather than %d for the formatting of the date. strftime(3) gave the a lot more information too.

- Thomas Backman
 
The extra $(( )) may still be useful because it removes the space that %e inserts before days less than 10.

The change to 09 is a deliberate change to sh in 9.0.
 
Back
Top