ここで解決策を確認しましたが、解決策が見つからないようです。私は約300kb /秒の非常に遅いWAN接続を扱っています。ダウンロードにはリモートボックスを使用していて、それから家にダウンロードしています。リモートサーバーとローカルサーバーの2つのディレクトリを1時間ごとにrsyncするcronジョブを実行しようとしています。私はすべてが機能しましたが、rsyncを転送するデータがたくさんある場合は重複し、同じファイルの2つのインスタンスを作成することになり、重複したデータが送信されます。
代わりに、rsyncコマンドを実行するスクリプトを呼び出したいのですが、rsyncが実行されていない場合に限りますか?
スクリプトを介して、「ロック」ファイルを作成できます。ファイルが存在する場合、cronジョブは実行をスキップする必要があります。それ以外の場合は続行する必要があります。スクリプトが完了すると、ロックファイルが削除されます。
if [-e/home/myhomedir/rsyncjob.lock] then echo"Rsyncジョブは既に実行中です...終了しています " exit fi touch /home/myhomedir/rsyncjob.lock #your code in here #delete lock fileジョブの終了時 rm /home/myhomedir/rsyncjob.lock
以前の解決策で提案された「ロック」ファイルの作成に関する問題は、ロックファイルを削除するスクリプトが異常終了した場合、ロックファイルがすでに存在している可能性があることです。これは、たとえば、ユーザーがrsyncプロセスを終了した場合、または停電が原因で発生する可能性があります。代わりに、この問題の影響を受けないflock
を使用する必要があります。
たまたま群れも使いやすいので、解決策は次のようになります。
flock -n lock_file -c "rsync ..."
-c
オプションの後のコマンドは、lock_fileに他のプロセスロックがない場合にのみ実行されます。何らかの理由でロックプロセスが終了すると、lock_fileでロックが解除されます。 -n
オプションは、群れが非ブロッキングであるべきだと言っているので、ファイルをロックしている別のプロセスがある場合、何も起こりません。
ロックファイルを使用しない簡単な解決策は、これを行うことです。
pgrep rsync > /dev/null || rsync -avz ...
これは、サーバーで実行する唯一のrsyncジョブである限り機能し、cronで直接実行できますが、出力をログファイルにリダイレクトする必要があります。
複数のrsyncジョブを実行する場合は、次のようなパターンでpgrepを完全なコマンドラインと照合することができます。
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/
上記の@Userで指定されたロックファイルの例を使用するには、トラップを使用して、何らかの理由でスクリプトが終了したときにロックファイルが削除されていることを確認する必要があります。
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
このようにして、スクリプトが終了する前にスクリプトが終了した場合でも、ロックファイルは削除されます。