JSintra
JSintra

Reputation:

Bash script, Illegal number: 08

I'm running a pretty simple bash script in ubuntu but have come up with a problem. If needed I'll post the whole script, but I've narrowed down the problem. Basically, I want to run some code every 15 seconds, so I started with this:

time=`date +%S`

time2=$((time%15))

if [ $time2 -eq 0 ]

then

etc, etc, etc....

The problem comes up when time is 08 seconds. The script terminates with Illegal number: 08. Adding to that, when using:

time2=$(($time%15))

instead of the illegal number error, it would terminate with Arithmetic expression: expecting EOF: "08%15"

I'm guessing 08 isn't interpreted as a number. Or there's some base issue, like it thinks it's in octal or something. Any help?

Upvotes: 5

Views: 7049

Answers (6)

jrrs
jrrs

Reputation: 98

you're right, it was interpreting it as octal. bourne shells do that for any number with a leading 0 in an Arithmetic Substition:

#~ $ echo $(( 010 ))
8
#~ $ echo $(( 0100 ))
64
#~ $ echo $(( 10#0100 ))
100
#~ $ echo $(( 40#lolwut ))
2213236429 

look in the manpage for 'base#' to see all the details about this '#-forcing' thing. you can get pretty ridiculous with it if you want to

Upvotes: 2

TheBonsai
TheBonsai

Reputation: 16545

Force Bash to interpret the number in decimal, no matter how many padded zeros:

time2=$((10#$time % 15))

Upvotes: 4

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507235

Try using the following flags instead

date +%-S

It says given the -, it won't pad. It has problems with the base, interpreting it as an octal integer.

Anyway, if you want to do something every 15 seconds, i find this one easier to follow:

while ((1)); do 
    echo do something now...
    sleep 15s
done

Upvotes: 4

pjc50
pjc50

Reputation: 1755

That does look like it's interpreting it as octal.

Try date +%S | sed -e 's/^0//'

Upvotes: 1

ephemient
ephemient

Reputation: 204946

Shortest solution:

time2=$(( ${time#0} % 15 ))

${var#glob} means "$var with glob removed from the beginning if present".

Upvotes: 6

David Webb
David Webb

Reputation: 193734

Since you're only interested in "every fifteen seconds" rather than running things on the minute exactly you could use date +%s (lowercase s) which will give you the number of seconds since the start of the epoch. This won't have a leading 0 so your script should run fine.

However, I would wonder about your code in a wider context. If the system is running very slow for some reason it could be possible for the script only be run second 14 and then second 16 meaning it will miss an execution.

It might be worth touching a file when you do whatever it is the script does and then performing your action when then last modified date of the file is 15 or more seconds ago.

Upvotes: 1

Related Questions