16

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.)

Alan H.
  • 16,219
  • 17
  • 80
  • 113

7 Answers7

20

The watch command is a good option. If you end up needing more control you can use a while loop:

while [ 1 ]
do
  cp source dest
  sleep 5s
done
Sage Mitchell
  • 1,563
  • 8
  • 31
16
while true
do
    cp file /other/location
    sleep 5
done

You don't even need to write a script for this, just type while true; do cp file /other/location; sleep 5; done at the bash prompt.

David Yaw
  • 27,383
  • 4
  • 60
  • 93
11

Perhaps watch will do:

watch -n 5 date
barti_ddu
  • 10,179
  • 1
  • 45
  • 53
4

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.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
3

Use the watch command.

Source

Community
  • 1
  • 1
ngen
  • 8,816
  • 2
  • 18
  • 15
2

One liner,

 while :; do cp from_file to_file; sleep 5; done
Alex Nolasco
  • 18,750
  • 9
  • 86
  • 81
1

not sure if this will work, but you could try it, basically it is an infinite loop, so you would have to terminate the script manually or add a filter for say the q key, when pressed sets copyFiles to 0

copyFile = 1
while [ ${copyFile} -eq 1 ]
do
    echo "Copying file..."
    cp file /other/location
    echo "File copied.  Press q to quit."
    read response
    [ "$response" = "q" ] && copyFile = 0
    sleep 5
done
cyberboxster
  • 723
  • 1
  • 6
  • 12
Sean
  • 97
  • 4