Como posso verificar se o rsync fez alguma alteração no bash?

12

Eu tenho um script que usa o rsync para sincronizar dados em um cenário remoto -> local. Imediatamente após a execução do comando rsync, verifique se o código de erro é igual a zero ou não. Se for zero, outros comandos serão executados. No entanto, isso não leva em conta o fato de que o rsync pode ter sido executado com êxito, mas na verdade não fez nenhuma alteração. Por esse motivo, a condição igual a zero será executada independentemente, o que é um pouco redundante.

rsync -aEivm --delete /path/to/remote/ /path/to/local/

if [ $? -eq 0 ]; then
    # Success do some more work!
else
    # Something went wrong!
    exit 1;
fi

Qual seria a melhor abordagem para expandir isso e verificar se realmente houve alguma alteração com base no comando rsync executado. Eu li que o sinalizador -i pode fornecer saída para o stdout, mas como isso pode ser colocado em um bloco condicional?

James White
fonte
Você chegou -vlá, por isso já está fornecendo as informações necessárias para sair ... por exemplo, uma lista de arquivos que foram realmente enviados. Se nada mudar, isso é justo ./.
Goldilocks
Ah! E se eu remover -v e usar -i em vez disso e usar uma verificação de cadeia não vazia no comando rsync?
James White
Parece que você mesmo encontrou a solução? :-)
Bjorn Munch
2
você pode usar a=$("rsync command"). Isto executar o rsynccomando e armazenar stdoutem a. Em seguida, você pode executar testes ema
nitishch
1
Você também pode adicionar um | grep /ou algo parecido e verificar o status de saída do grep $?, deve ser 1 se não houver saída.
Bjorn Munch

Respostas:

9

Com base nos comentários da minha pergunta original, faça o rsync output para stdout com o sinalizador -i e use uma condição de verificação sem string para ver se alguma coisa realmente mudou na verificação do código de erro. O agrupamento do comando rsync em uma variável permite que a verificação seja feita.

RSYNC_COMMAND=$(rsync -aEim --delete /path/to/remote/ /path/to/local/)

    if [ $? -eq 0 ]; then
        # Success do some more work!

        if [ -n "${RSYNC_COMMAND}" ]; then
            # Stuff to run, because rsync has changes
        else
            # No changes were made by rsync
        fi
    else
        # Something went wrong!
        exit 1
    fi

Possível desvantagem: você precisa perder a saída detalhada, mas sempre pode registrá-la em um arquivo.

James White
fonte
1

Eu queria uma solução mais rigorosa. Não quero grep Number of created files:(a mensagem pode estar em outro idioma) ou remover todas as linhas, exceto duas na -vsaída (quem sabe qual resumo rsyncserá impresso na próxima versão?).

Eu descobri que você pode definir o formato do rsynclog de um, mas não o formato do seu stdout (consulte man rsyncd.conf).

Por exemplo, adicione um "Arquivo alterado!" para cada linha com um arquivo realmente alterado e, grepem seguida, para ele:

rsync -a \
    --log-file=/tmp/rsync.log \
    --log-file-format="File changed! %f %i" \
    source-dir target-dir

if fgrep "File changed!" /tmp/rsync.log > /dev/null; then
    echo "rsync did something!"
fi
Victor Sergienko
fonte