2012-02-22 10 views
17

Qui ho trovato una soluzione ma non riesco a trovarne una. Ho a che fare con una connessione wan molto lenta a circa 300kb/sec. Per i miei download sto usando una scatola remota, e poi li sto scaricando a casa mia. Sto cercando di eseguire un cronjob che eseguirà il rsync di due directory sul mio server remoto e locale ogni ora. Ho trovato tutto funzionante, ma se ci sono molti dati da trasferire gli rsyncs si sovrappongono e finiscono per creare due istanze dello stesso file, quindi duplicare i dati inviati.cronjob Rsync che verrà eseguito solo se rsync non è già in esecuzione

Desidero invece chiamare uno script che esegua il comando rsync ma solo se rsync non è in esecuzione?

+0

Ecco una risposta simile a una singola istanza di script della shell, ma accetta la risposta selezionata e la rende più solida. http://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at – physicsmichael

risposta

7

Tramite lo script è possibile creare un file "di blocco". Se il file esiste, il cronjob dovrebbe saltare la corsa; altrimenti dovrebbe procedere. Una volta completato lo script, dovrebbe eliminare il file di blocco.

 
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 
+0

ok, sono davvero nuovo per l'intera cosa di scripting, ha trovato questo: 'code'if (set -o noclobber; echo" locked ">" $ lockfile ") 2>/dev/null; quindi trap 'rm -f "$ lockfile"; uscita $?'INT TERM EXIT echo "Blocco riuscito"> & 2 rm -f "$ file di lock" altro echo "Blocco non riuscito - uscita"> & 2 exit 1 fi '\ Codice delle – mfpockets

+0

Non ha bisogno di essere quel complesso . Basta creare un file di blocco. Utilizzare if -e per verificare l'esistenza del file e se esiste exit; altrimenti procedere. – bubbly

+0

Grazie, questo aiuterà una volta che posso capire come fare correttamente i file di blocco. :(non utile per un principiante – mfpockets

73

Il problema con la creazione di un file "lock", come suggerito in una soluzione precedente, è che il file di blocco potrebbe già esistere se lo script responsabile per la rimozione termina in modo anomalo. Questo potrebbe accadere ad esempio se l'utente termina il processo rsync o a causa di un'interruzione dell'alimentazione. Invece si dovrebbe usare flock, che non soffre di questo problema.

Come accade gregge è anche facile da usare, in modo che la soluzione sarebbe semplicemente aspetto:

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

Il comando dopo l'opzione -c viene eseguita solo se non v'è altro blocco di processo sulla file_lock. Se il processo di blocco per qualsiasi motivo termina, il blocco verrà rilasciato su lock_file. Le opzioni -n dicono che il flock dovrebbe essere non bloccante, quindi se c'è un altro processo che blocca il file non accadrà nulla.

+1

Questo è assolutamente corretto. Un'altra soluzione è utilizzare i lease, anziché i blocchi, in modo che il blocco scada dopo un periodo di tempo, a meno che il lease non venga rinnovato. Un leasing è fondamentalmente un lockfile con un timestamp in esso. – cha0site

+6

ha funzionato perfettamente. Questa dovrebbe essere la risposta accettata. – chovy

+1

Va notato che questo non funzionerà su NFS – WarmWaffles

4

Una soluzione semplice senza l'utilizzo di un file di blocco è quello di fare solo questo:

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

Questo funziona fintanto che è l'unico lavoro rsync si esegue sul server, e quindi è possibile eseguire questo direttamente in cron, ma dovrai reindirizzare l'output in un file di log.

Se fate eseguire più processi rsync, è possibile ottenere pgrep per abbinare contro la linea di comando completa con un modello come questo:

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/ 
2

Per utilizzare il file di blocco esempio dato da @User sopra, una trappola deve essere utilizzato per verificare che il file di blocco venga rimosso quando lo script viene chiuso per qualsiasi motivo.

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 

In questo modo il file di blocco verrà rimosso anche se lo script esce prima della fine dello script.

+0

Questa è in realtà la soluzione migliore – berezovskyi