Заставьте rsync сообщать, были ли обновлены какие-либо локальные файлы.

Заставьте rsync сообщать, были ли обновлены какие-либо локальные файлы.

Я запускаю rsync для передачи данных с удаленного хоста на локальный хост.

rsync -a --update user@remotehost:/files/ ~/files/

Я запускаю эту команду из Java и использую код выхода, чтобы выяснить, была ли она успешной или нет.

Можно ли заставить эту команду сообщать, были ли изменены какие-либо локальные файлы? Отчетность через код выхода была бы идеальной.

решение1

Вы не можете rsyncсказать вам это через код выхода. Коды выхода имеют задокументированные предопределенные значения.

Я думаю, что лучшим способом сделать это из Java будет добавить опцию, --info=NAMEпозволяющую упоминать только обновленные имена каталогов и файлов:

rsync -a --info=NAME --update user@remotehost/files/ ~/files/

Эта команда выводит имена обновленных файлов и каталогов, по одному в строке, на стандартный вывод (fd = 0).

Затем вы собираете выходные данные rsyncи подсчитываете количество новых строк в строке.

Я думаю, что хороший способ собрать выходные данные javaможно найти в этом ответе, но я его не пробовал:https://stackoverflow.com/a/9048519/5484716

Делатьнетиспользовать redirectErrorStreamили любым другим способом объединить стандартный вывод и стандартные потоки ошибок. Если вы это сделаете, вы будете считать сообщения об ошибках обновленными файлами, а не тем, что вам нужно.

решение2

Основываясь на идее @DavidKing позволить rsync выводить скопированные имена файлов и расширенной информацией от @yashma о том, что grep выйдет с ненулевым кодом выхода, если stdin пуст, мы можем придумать этот удовлетворительно короткий и загадочный однострочный код:

# prints file list, exits nonzero when that list is empty
rsync -a --info=NAME --update user@remotehost:/files/ ~/files/ | grep .

решение3

Флаг --infoon rsyncвыведет путь к любому переданному файлу. Код выхода rsyncуказывает на успех/неудачу, поэтому вы не сможете использовать его без обертывания скрипта вокруг команды, например

#!/bin/bash

files=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)

if [ $files = "" ]; then
  # files weren't transferred
  exit 0
else
  # files were transferred
  exit 1
fi

и затем вызов этого скрипта из Java вместо rsyncкоманды напрямую. rsyncвероятно, выведет некоторые другие строки текста в начале и конце передачи, поэтому вам, возможно, придется скорректировать оператор, ifчтобы учесть дополнительные строки вывода, но основная идея будет работать.

решение4

Способ получения информации по коду возврата — написать скрипт оболочки, который вызывает rsyncи выполняет скрипт оболочки из java. С этим связаны некоторые серьезные проблемы, которые я опишу ниже. Скрипт оболочки может выглядеть так:

#!/bin/sh
if OUTPUT=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)
then
    if [ "$OUTPUT" != "" ]                   # got output?
    then
        exit 0  # yes, success, "some" files were updated
    fi
fi
exit 1  # either rsync failed or no files were updated

Основная проблема в том, что вы не сможете сказать, успешно ли завершился сам процесс синхронизации. Вы знаете только, были ли обновлены файлы или нет. Вот почему я бы рекомендовал собирать вывод в java и подсчитывать строкиипроверьте код возвратав Яве.

Связанный контент