views:

766

answers:

5

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?

+1  A: 

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.

Dave Webb
I know what you mean, some seconds are jumped/ignored. The purpose of this script however was just to test with seconds, because I'll be using this for every 15 minutes.But I'll probably have to check your answer, because I might not want this script constantly running.
+1  A: 

Shortest solution:

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

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

ephemient
Thank you, that was exactly what I was looking for.
+1  A: 

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

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

pjc50
That also worked.
+3  A: 

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
Johannes Schaub - litb
Thanks, I'll take that into account for future work.
Why not use it for the current script too? It gets rid of the problem in an elegant way (adding only one char), telling date directly what you want instead of snipping the zero away afterwards.
Johannes Schaub - litb
Oh, I will, but not immediately. When I change to minutes I'll definetly be using your code.
GNU coreutils date supports %-S, but I don't see it specified by POSIX, so I'm unsure about its portability.
ephemient
oh, good point about compatibility. He's have to keep an eye on that if he uses "%-S".
Johannes Schaub - litb
A: 

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

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