web-dev-qa-db-ja.com

rsyncがまだ実行されていない場合にのみ実行されるrsynccronjob

ここで解決策を確認しましたが、解決策が見つからないようです。私は約300kb /秒の非常に遅いWAN接続を扱っています。ダウンロードにはリモートボックスを使用していて、それから家にダウンロードしています。リモートサーバーとローカルサーバーの2つのディレクトリを1時間ごとにrsyncするcronジョブを実行しようとしています。私はすべてが機能しましたが、rsyncを転送するデータがたくさんある場合は重複し、同じファイルの2つのインスタンスを作成することになり、重複したデータが送信されます。

代わりに、rsyncコマンドを実行するスクリプトを呼び出したいのですが、rsyncが実行されていない場合に限りますか?

21
mfpockets

スクリプトを介して、「ロック」ファイルを作成できます。ファイルが存在する場合、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
9
souser

以前の解決策で提案された「ロック」ファイルの作成に関する問題は、ロックファイルを削除するスクリプトが異常終了した場合、ロックファイルがすでに存在している可能性があることです。これは、たとえば、ユーザーがrsyncプロセスを終了した場合、または停電が原因で発生する可能性があります。代わりに、この問題の影響を受けないflockを使用する必要があります。

たまたま群れも使いやすいので、解決策は次のようになります。

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

-cオプションの後のコマンドは、lock_fileに他のプロセスロックがない場合にのみ実行されます。何らかの理由でロックプロセスが終了すると、lock_fileでロックが解除されます。 -nオプションは、群れが非ブロッキングであるべきだと言っているので、ファイルをロックしている別のプロセスがある場合、何も起こりません。

86
J. P. Petersen

ロックファイルを使用しない簡単な解決策は、これを行うことです。

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/
5
dannyw

上記の@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

このようにして、スクリプトが終了する前にスクリプトが終了した場合でも、ロックファイルは削除されます。

3