Cron e rsync usando o bloqueio de arquivo, mas existe uma maneira melhor no Mac OS X Server?

6

Eu tenho este script bash e é executado via cron em intervalos regulares:

#!/bin/bash

RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/Users/admin/Documents/Backup/rsync-key
RUSER=philosophy
RHOST=example.com
RPATH=data/
LPATH="/Volumes/G Technology G Speed eS/Backup"
LOCKFILE=/Users/admin/Documents/backup.isrunning

if [ ! -e $LOCKFILE ]; then
    touch $LOCKFILE
    $RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
    rm $LOCKFILE
else
    echo "Rsync - Backup still running"
fi

O backup pode levar algum tempo, de alguns minutos a dias, e se eu executar o backup via cron a cada 6 horas, o que eu não quero é duas instâncias desta execução ao mesmo tempo. Então, o que eu fiz foi criar um mecanismo de bloqueio simples. Mas estou preocupado que, se o script for eliminado na metade do caminho, por qualquer motivo, esse arquivo de bloqueio sempre estará lá e a rotina de backup não será executada.

Existe uma maneira de melhorar isso para ser mais à prova de erros?

Obrigado

Scott

EDITAR: O script bash final que estou usando agora graças à resposta abaixo:

#!/bin/bash

RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/Users/admin/Documents/Backup/rsync-key
RUSER=philosophy
RHOST=example.com
RPATH=data/
LOCKFILE=/Users/admin/Documents/Backup/backup.isrunning

if [ ! -e $LOCKFILE ]
then
    echo $$ >"$LOCKFILE"
else
    PID=$(cat "$LOCKFILE")
    if kill -0 "$PID" >&/dev/null
    then
        echo "Rsync - Backup still running"
        exit 0
    else
        echo $$ >"$LOCKFILE"
        echo "Warning: previous backup appears to have not finished correctly"
    fi
fi

LPATH="/Volumes/G Technology G Speed eS/Backup"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Catalogue"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Digital"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Finance"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Image Libraries"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/IT Desk"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Office"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Studio"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

LPATH="/Volumes/G Technology G Speed eS/Toffee Apple"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH

rm -f "$LOCKFILE"
    
por Brady 21.02.2011 / 17:48

2 respostas

4

Se você colocar o PID do script no arquivo de bloqueio, se o arquivo de bloqueio existir quando uma nova instância for iniciada, você poderá ler o PID e verificar se o script ainda está em execução. Se o script não estiver sendo executado, limpe-o, coloque o PID da instância atual no arquivo de bloqueio e inicie o rsync, caso contrário, imprima uma mensagem 'ainda em execução' e saia.

EDITAR:

#!/bin/bash
backup() {
    RSYNC=/usr/bin/rsync
    SSH=/usr/bin/ssh
    KEY=/Users/admin/Documents/Backup/rsync-key
    RUSER=philosophy
    RHOST=example.com
    RPATH=data/
    LPATH="/Volumes/G Technology G Speed eS/Backup"

    $RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
}

LOCKFILE=/Users/admin/Documents/backup.isrunning

if [ ! -e "$LOCKFILE" ]
then
    echo $$ >"$LOCKFILE"
    backup
else
    PID=$(cat "$LOCKFILE")
    if kill -0 "$PID" >&/dev/null
    then
        echo "Rsync - Backup still running"
        exit 0
    else
        echo $$ >"$LOCKFILE"
        echo "Warning: previous backup appears not to have finished correctly"
        backup
    fi
fi

rm -f "$LOCKFILE"
    
por 21.02.2011 / 20:30
1

Se você estiver configurando vários backups, talvez queira dar uma olhada em LBackup , que oferece bloqueio e também oferece suporte total a backups pull. Mais informações sobre as vantagens de um backup pull estão disponíveis no seguinte URL: link

Se você verificar o código-fonte do LBackup, verá como o sistema de bloqueio é implementado usando um trap. A sugestão acima sobre o uso de um PID também é uma boa ideia. Com essa abordagem, o servidor inteiro deve falhar e a interceptação não terá a chance de ser ativada.

    
por 14.07.2012 / 23:09