То, что у вас было, - хорошее начало, но нужно помнить, что xargs будет обрабатывать строки стандартного ввода в группах. (В этом и заключается его цель: брать неограниченное количество строк ввода и выполнять команду несколько раз, каждый раз с подмножеством строк ввода в качестве аргументов командной строки.) Когда files.tar.gz
имеет огромное количество файлов, xargs будет делать tar zcvf /tmp/file-backup.tar.gz
на подмножестве их одновременно! В результате /tmp/file-backup.tar.gz
будет содержать только последнее подмножество файлов!
Я предполагаю, что, поскольку вы указали пути как path/.../...
, все пути будут относительными.
Вот лучшее решение (см. «Примечания» ниже по использованию tar ...|while read...
):
(tar ztf files.tar.gz|while read f; do if [ -f "$f" -o -h "$f" ]; then echo "$f" ; fi; done)|tar Tcfz - /tmp/`date '+%Y%m%d_%H%M%S'`.file-backup.tar.gz
Команда tar
создает файл с именем /tmp/yyyymmdd_hhmmss.file-backup.tar.gz
, содержащий список файлов, поставляемых в его стандартном вводе, который представляет собой список файлов и символических ссылок в files.tar.gz
.
Наконец, вы можете рассмотреть несколько альтернатив, которые могут упростить хостинг:
- Сохранять только файлы, которые действительно изменились, вместо сохранения всех файлов.
- Или вместо сохранения файлов в файл tar / gzip переименуйте файлы на месте; таким образом, вы сразу увидите, какие файлы имеют более новую версию (и), без необходимости сначала просматривать несколько различных
/tmp/yyyymmdd_hhmmss.file-backup.tar.gz
файлов:
(TAG=`date '+%Y%m%d_%H%M%S'` ; tar ztf files.tar.gz|while read f; do if [ -f "$f" -o -h "$f" ]; then mv "$f" "$f.$TAG" ; fi; done)
ПРИМЕЧАНИЕ: tar ztf ...|while read f
гарантирует, что имена файлов, содержащие пробелы, не вызовут проблемы. Проще
for f in `tar ztf files.tar.gz`; do...
не будет работать, если в files.tar.gz
есть файлы с пробелами в их имени.