Как я могу использовать FIND для рекурсивного резервного копирования нескольких репозиториев Subversion

На данный момент наш скрипт резервного копирования явно запускает svnadmin hotcopy для каждого из наших репозиториев каждую ночь. Все наши репозитории хранятся в родительском каталоге (/usr/local/svn/repos). В нашем сценарии резервного копирования есть строка для каждого репозитория в этом каталоге: svnadmin hotcopy /usr/local/svn/repos/myrepo1 /USR/локальные/резервное копирование/myrepo1

Вместо того, чтобы вручную добавлять новую строку для каждого нового репозитория, который мы подключаем к сети, я надеялся использовать команду find для запуска горячего копирования svnadmin для каждого каталога, который он находит в /usr/local/svn/repos.

Пока у меня есть:

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} \;

, где для простоты я заменил "svnadmin hotcopy" на "echo". Результат которого:

/usr/local/backup/usr/local/svn/repos/ure
/usr/local/backup/usr/local/svn/repos/cheetah
/usr/local/backup/usr/local/svn/repos/casemgt
/usr/local/backup/usr/local/svn/repos/royalliver
/usr/local/backup/usr/local/svn/repos/ure_andras
/usr/local/backup/usr/local/svn/repos/profserv
/usr/local/backup/usr/local/svn/repos/frontoffice
/usr/local/backup/usr/local/svn/repos/ure.orig
/usr/local/backup/usr/local/svn/repos/projectcommon
/usr/local/backup/usr/local/svn/repos/playground
/usr/local/backup/usr/local/svn/repos/casegen

Проблема в том, что полный путь включен в {}. Мне нужен только последний элемент имени каталога, переданный в -exec

Результат, который я хочу:

/usr/local/backup/ure
/usr/local/backup/cheetah
/usr/local/backup/casemgt
/usr/local/backup/royalliver
/usr/local/backup/ure_andras
/usr/local/backup/profserv
/usr/local/backup/frontoffice
/usr/local/backup/ure.orig
/usr/local/backup/projectcommon
/usr/local/backup/playground
/usr/local/backup/casegen

Я в значительной степени застрял на этом этапе. Может кто-нибудь помочь мне здесь? Заранее спасибо, Дэйв


person David Corley    schedule 23.10.2009    source источник


Ответы (4)


Вы были на правильном пути. Попробуй это:

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -printf "%f\0" | xargs -0 -I{} echo svnadmin hotcopy /usr/local/svn/repos/\{\} /usr/local/backup/\{\}

%f похож на basename, а нуль плюс -0 в xargs гарантирует, что имена с пробелами и т. д. будут успешно переданы.

Просто удалите echo и внесите необходимые изменения, и это должно помочь.

person Dennis Williamson    schedule 23.10.2009
comment
Я нашел это решение идеальным. Спасибо Денис. - person David Corley; 27.10.2009

поставить команду cut в конце

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} \| cut -f1,2,3,9 -d"/"
person Vijay    schedule 23.10.2009

Как насчет добавления фильтра sed, вырезающего среднюю часть?

sed 's/usr.local.svn.repos.//g'

Добавлено вот так

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} ";" | sed 's/usr.local.svn.repos.//g'
person epatel    schedule 23.10.2009

ls -al /usr/local/svn/repos/ |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo /usr/local/svn/repos/zzyggy

Это немного долго, но это делает свое дело. Вам не нужно делать все с помощью find, когда есть много других команд оболочки, хотя, если бы мне пришлось писать такой скрипт, я бы сделал это на Python и оставил оболочку для интерактивной работы.

ls -al перечисляет все файлы в указанном каталоге с атрибутами

grep '^d' выбирает строки, начинающиеся с d, которые являются каталогами

sed удаляет все символы слева от фактического имени каталога. Возможно, вам придется добавить или удалить некоторые точки

xargs берет список имен каталогов и выдает их по одному. Я указал zzyggy как имя для подстановки в выполняемой команде, но вы можете выбрать то, что вам нравится. Конечно, вы бы заменили echo своей командой svnadmin.

Если бы это было в сценарии оболочки, вы действительно должны были бы сделать это

SVNDIRNAME="/usr/local/svn/repos"
ls -al $SVNDIRNAME |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo $SVNDIRNAME/zzyggy

но я решил показать неправильный и правильный путь только для того, чтобы объяснить этот момент. Я собираюсь пометить это некоторым тегом оболочки, но я все еще думаю, что сценарий Python — лучший способ решить такого рода проблемы в 21 веке.

person Michael Dillon    schedule 23.10.2009
comment
Говоря об интерактивной работе, ls на самом деле не был предназначен для таких вещей, а find идеально для этого подходит. Кроме того, возможно, ваш sed не понимает 's/^.\{27\}//'? (Я не считал ваши точки, так что это просто предположение). И если вам нужно анализировать ls таким образом, по крайней мере, используйте cut вместо этой нелепой команды sed. Я решил показать неправильный и правильный путь - Использование переменной имеет значение? Извините, но вы только что купили себе минус 21 века. - person Dennis Williamson; 23.10.2009
comment
Как я уже сказал, если бы у меня действительно была эта работа, я бы написал скрипт на Python. В свое время программирование оболочки было в порядке вещей, но чем быстрее мы все это освоим, тем лучше. - person Michael Dillon; 23.10.2009