Rsync cronjob that will only run if rsync isn't already running

烂漫一生 提交于 2019-12-20 09:37:10

问题


I have checked for a solution here but cannot seem to find one. I am dealing with a very slow wan connection about 300kb/sec. For my downloads I am using a remote box, and then I am downloading them to my house. I am trying to run a cronjob that will rsync two directories on my remote and local server every hour. I got everything working but if there is a lot of data to transfer the rsyncs overlap and end up creating two instances of the same file thus duplicate data sent.

I want to instead call a script that would run my rsync command but only if rsync isn't running?


回答1:


Via the script you can create a "lock" file. If the file exists, the cronjob should skip the run ; else it should proceed. Once the script completes, it should delete the lock file.

if [ -e /home/myhomedir/rsyncjob.lock ]
then
  echo "Rsync job already running...exiting"
  exit
fi

touch /home/myhomedir/rsyncjob.lock

#your code in here

#delete lock file at end of your job

rm /home/myhomedir/rsyncjob.lock



回答2:


The problem with creating a "lock" file as suggested in a previous solution, is that the lock file might already exist if the script responsible to removing it terminates abnormally. This could for example happen if the user terminates the rsync process, or due to a power outage. Instead one should use flock, which does not suffer from this problem.

As it happens flock is also easy to use, so the solution would simply look like this:

flock -n lock_file -c "rsync ..."

The command after the -c option is only executed if there is no other process locking on the lock_file. If the locking process for any reason terminates, the lock will be released on the lock_file. The -n options says that flock should be non-blocking, so if there is another processes locking the file nothing will happen.




回答3:


A simple solution without using a lock file is to just do this:

pgrep rsync > /dev/null || rsync -avz ...

This will work as long as it is the only rsync job you run on the server, and you can then run this directly in cron, but you will need to redirect the output to a log file.

If you do run multiple rsync jobs, you can get pgrep to match against the full command line with a pattern like this:

pgrep -f rsync.*/data > /dev/null || rsync -avz --delete /data/ otherhost:/data/
pgrep -f rsync.*/www  > /dev/null || rsync -avz --delete /var/www/ otherhost:/var/www/



回答4:


To use the lock file example given by @User above, a trap should be used to verify that the lock file is removed when the script is exited for any reason.

if [ -e /home/myhomedir/rsyncjob.lock ]
then
  echo "Rsync job already running...exiting"
  exit
fi

touch /home/myhomedir/rsyncjob.lock

#delete lock file at end of your job

trap 'rm /home/myhomedir/rsyncjob.lock' EXIT

#your code in here

This way the lock file will be removed even if the script exits before the end of the script.



来源:https://stackoverflow.com/questions/9390134/rsync-cronjob-that-will-only-run-if-rsync-isnt-already-running

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!