В основном я хочу переместить файлы на другой сервер при создании, сохраняя структуру каталогов. У меня есть решение, но в нем нет элегантности. Кроме того, я чувствую, что упускаю очевидный ответ, поэтому заранее благодарю за вашу помощь, и я полностью понимаю, скучно ли это вам.
Ситуация
У меня есть сервер с ограниченным дисковым пространством (назовем его 'Tiny') и сервер хранения. Tiny создает файлы время от времени. Я хочу хранить их автоматически на сервере хранения и удалять оригиналы, когда это безопасно. Я должен сохранить структуру каталогов крошечные. Я не знаю заранее, как выглядит структура dir. То есть все файлы создаются в каталоге /some/dir/
, но каталоги этого создаются на лету. Они должны быть размещены в /other/fold/
на сервере хранилища, сохраняя подстроку под /some/dir
. Например:
/some/dir/bla/foo/bar/snap_001a
на крошечном ---> становится /other/fold/bla/foo/bar/snap_001a
на сервере хранения. Все они называются snap_xxxx
wgere xxxx - это четырехбуквенная буквенно-цифровая строка.
Мое старое решение
Теперь я подумал перебрать файлы и scp
их. Как только scp закончится и вернется без ошибок, файлы на крошечном удаляются с rm
.
#!/bin/bash
# This is invoked by a cronjob ever once in a while.
files=$(find /some/dir/ -name snap_*)
IFS='
'
for current in $files; do
name=$(basename $current) # Get base name (i.e. strip directory)
dir=$(dirname $current) # Get the directory name of the curent file on tiny
dir=${dir/\/some\/dir/\/other\/fold} # Replace the directory root on tiny with the root on the storage server
ssh -i keyfile myuser@storage.server.net \
mkidir -p $dir # create the directory on the storage server and all parents if needed
scp -i keyfile $current myuser@storage.server.net:$dir$name \
&& rm $current # remove files on success
done
Это, однако, кажется мне излишне сложным и, возможно, подверженным ошибкам . Я думал о rsync
, но при копировании отдельных файлов нет возможности создать каталог, и его родители, если они не существуют. У кого-нибудь есть идея, лучше, чем моя?
Что я закончил использовать после этой темы
rsync -av --remove-sent-files --prune-empty-dirs \
-e 'ssh -i /full/path/to/keyfile' \
--include="*/" --include="snap_*" --exclude="*" \
/some/dir/ myuser@storage.server.com:/other/fold/
Более свежие версии, чем та, которую я использовал, взяли --remove-source-files
вместо --remove-sent-files
. Первое из них более красноречиво, так как более понятно, какие файлы удаляются. Также --dry-run
является хорошим вариантом для проверки ваших параметров ДО фактического использования rsync.
Спасибо Алексу Ховански за решение и Дугласу Лидеру за заботу!