como sincronizar dois diretório?

2

Eu quero usar o crontab para sincronizar dois diretórios entre minha partição linux e a partição do windows desta forma:

24 9 * * * cp -r /home/fan/Data /media/T/Data

Mas criaria um diretório chamado Data no diretório Data de origem, em vez de copiar o arquivo ausente do diretório de origem. Não consigo encontrar uma opção adequada no manual cp para resolver isso perfeitamente. Como posso copiar o arquivo ausente (eles existem no diretório de destino) do src para dir.

E, a propósito, parece que o disco T foi montado para executar o comando copy, como montar automaticamente o disco quando eu precisar executar o comando (o comando mount deve ser executado como root).

E como posso obter a mensagem de erro se o comando tiver uma exceção?

    
por Ziu 06.04.2014 / 16:39

3 respostas

1

Para resolver a parte da mensagem de erro da pergunta, você pode optar por executar um script do cron em vez do comando do sistema.

24 9 * * * /usr/local/sbin/sync_data.sh

Crie o arquivo como /usr/local/sbin/sync_data.sh , fornecendo a propriedade raiz e a permissão de execução: chown root:root /usr/local/sbin/sync_data.sh && chmod 0700 /usr/local/sbin/sync_data.sh . O conteúdo do script está abaixo.

#!/usr/bin/env bash
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root." 1>&2
    exit 1
fi

# [ ] vs [[ ]] : http://mywiki.wooledge.org/BashFAQ/031

dir_src="/home/fan/Data/"
dir_dst="/media/T/"

# A Boolean to know if running interactively or not
b_interactive=1
if [[ -v PS1 ]] ; then # The "-v PS1" method is for BASH 4.2+
    $b_interactive=0   # Could also use [[ -z "$PS1" ]]
fi

# Send messages to console or syslog.
function notify() {
    message="$1"
    if [[ $b_interactive -eq 1 ]] ; then
        echo "$message"
    else
        # eval combines args into a single string for execution...
        eval $cmd_logger -p err "$0: $message"
    fi
}

# If the mount point if not currently mounted...
if [[ "$(grep $dir_dst /proc/mounts)" = "" ]] ; then
    # Try to mount the directory.
    mount $dir_dst

    # Send a message to console or syslog.
    if [[ $? -ne 0 ]] ; then
        notify("$0 failed to mount $dir_dst")
        exit 1;
    fi
fi

# Create a backup directory if it does not exist
if [[ -d $dir_dst ]] ; then
    mkdir -p $dir_dst 2>/dev/null
fi

# A one-way sync to dir_dst, deleting files that no longer exist in DIR_SRC...
rsync -a --delete $dir_src $dir_dst &> /dev/null

# Check the return status of last command...
if [ $? -eq 0 ]; then
    notify("$0: the rsync process succeeded.");
else
    notify("$0: the rsync process failed.");
fi

unset dir_src
unset dir_dst
unset b_interactive
    
por 06.04.2014 / 18:18
7

A ferramenta para sincronização de dados é rsync . Você pode sincronizar no nível do diretório ou apenas no conteúdo de um diretório da seguinte forma:

Exemplos

sincronização de diretório
24 9 * * * rsync -a /home/fan/Data /media/T/
sincronização de conteúdos
24 9 * * * rsync -a /home/fan/Data/ /media/T/Data/

O primeiro exemplo sincronizará o diretório Data de /home/fan para o diretório /media/T . O segundo exemplo irá sincronizar o conteúdo de Data para o diretório /media/T/Data .

Como uma dica adicional, vou sincronizar com os diretórios de destino usando essa notação:

24 9 * * * rsync -a /home/fan/Data/ /media/T/Data/.

O /. eu acho mais óbvio ao ler meus comandos rsync .

Exemplos de comportamento

Usar rsync é provavelmente um dos problemas mais confusos com os quais lidei quando estou treinando novos usuários.

Dados da amostra:

$ tree home/fan/Data/
home/fan/Data/
|-- file1
|-- file2
|-- file3
|-- file4
'-- file5
1. Sincronizando o conteúdo dos dados do diretório
$ rsync -a home/fan/Data/ media/T/

Observe que colocamos o conteúdo de Data em T .

$ tree media/T/
media/T/
|-- file1
|-- file2
|-- file3
|-- file4
'-- file5

0 directories, 5 files
2. sincronizando o diretório
$ rsync -a home/fan/Data media/T/

Observe que colocamos o diretório Data em T .

$ tree media/T/
media/T/
'-- Data
    |-- file1
    |-- file2
    |-- file3
    |-- file4
    '-- file5

1 directory, 5 files
    
por 06.04.2014 / 17:09
2

Usando rsync :

24 9 * * * rsync -a /home/fan/Data/ /media/T/Data

Adicione o / extra no final do nome do diretório de origem, que informará rsync para copiar o conteúdo em vez do diretório completo. rsync também evitará copiar arquivos que tenham os mesmos timestamps / size (ou seja, aqueles que não precisam ser copiados em 99,99% dos casos).

Considere também usar a opção --inplace para rsync para acelerar o processo se você estiver sincronizando arquivos no mesmo sistema. Na página do manual:

--inplace
    This option changes how rsync transfers a file when its data needs to be
    updated: instead of the default method of creating a new copy of the file and
    moving it into place when it is complete, rsync instead writes the updated
    data directly to the destination file.

No entanto, existem prós e contras para esta opção, provavelmente a maior desvantagem é que, se a sincronização for interrompida, o arquivo de destino será deixado em um estado inconsistente que só pode ser corrigido iniciando novamente.

    
por 06.04.2014 / 17:08