Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a tiny Bash shell script to repeat an action every 5 seconds?

I want to copy a file from one location to another every five seconds. I don’t want to set up a cronjob because this is only temporary and needs to be fully under my control.

Can I write a .sh that will do this?

(I’m on Mac OS X.)

like image 572
Alan H. Avatar asked Dec 21 '10 18:12

Alan H.


People also ask

How do you wait 30 seconds in bash?

It is as easy as typing sleep N . This will pause your script for N seconds, with N being either a positive integer or a floating point number.

How do I run a Linux script in 5 seconds?

What you could do is write a shell script with an infinite loop that runs your task, and then sleeps for 5 seconds. That way your task would be run more or less every 5 seconds, depending on how long the task itself takes. You can create a my-task.sh file with the contents above and run it with sh my-task.sh .


1 Answers

One potential problem that most of the answers share (including the ones using the watch command) is that they can drift. If that's not a problem, then don't worry about it, but if you want to the command to be executed as closely as possible to once every 5 seconds, read on.

This:

while : ; do cp from_file to_file ; sleep 5 ; done

will sleep for 5 seconds between file copies -- which means that if the copy takes 2 seconds, the loop will run every 7 seconds.

If instead you want to start the cp command every 5 seconds regardless of how long it takes, you can try something like this:

while : ; do
    now=$(date +%s) # current time in seconds
    remaining=$((5 - now % 5))
    sleep $remaining
    cp from_file to_file
done

This computes the seconds remaining until the next multiple of 5 (1 to 5 seconds) and sleeps for that long, so as long as the cp command finishes in less than 5 seconds, it will run it every 5 seconds. If it takes 2 seconds, it will sleep 3 seconds before running it again, and so forth.

(If the command takes longer than 5 seconds, it will skip one or more iterations. If you want to avoid that -- which means you might have two or more cp commands running in parallel -- you can run the cp command in background: cp from_file to_file &.)

You can combine the computations into a single expression if you like. I used named variables for clarity.

like image 105
Keith Thompson Avatar answered Sep 30 '22 19:09

Keith Thompson