
Я запускаю 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
Флаг --info
on 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 и подсчитывать строкиипроверьте код возвратав Яве.