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