Я пытаюсь автоматизировать удаленное резервное копирование на нашем сервере CentOS, я запускаю текущую команду:
nice -n 10 mv -vfb /media/localbackup/* /media/remotebackup/
однако, когда это запущено, я получаю следующую ошибку, и файлы не перемещаются
mv: inter-device move failed: `/media/localbackup/04-21-13' to `/media/remotebackup/04-21-13'; unable to remove target: Is a directory
Мне сказали, что лучше использовать cp, но это не приведет к удалению файлов впоследствии, и мне нужно удалить файлы после успешного резервного копирования.
Я также предлагаю вам использовать rsync
вместо того mv
, но добавив к @ Ответ Хартмута:
rsync -abmv --remove-source-files /media/localbackup /media/remotebackup/
find /media/localbackup -depth -type d -empty -delete
И здесь 2 дополнения:
-m
(--prune-empty-dirs
) параметр в rsync
, который в моей версии 3.0.7 протокола версии 30 говорит: удалить пустые цепочки каталогов из списка файлов, но по какой-то причине этого не делает. Также нет ошибок (не единственный, кто это заметил).find
команда, которая удалит пустые каталоги.теперь причина против cp
&& rm
в том, что cp
может выйти из строя на полпути. В следующий раз, когда вы захотите сделать резервную копию, вы попадете в странную ситуацию (частично скопированные файлы, чтобы назвать худший случай). Кроме того, следующая резервная копия не будет знать, что делать с ранее скопированными файлами, которые не были удалены. С другой стороны rsync
отлично охватывает эти аспекты.
Кроме того, использование сценария (как следует из первого ответа) для выполнения того, что уже делает rsync, но, что еще хуже, недопустимо (извините, Hauke Laging :-)). Здесь не нужно изобретать велосипед.
Я обнаружил, что часто хочу проделать некоторые операции с файлами, сохраняя при этом структуру их каталогов. По этой причине я определил функцию bash filtercmd
. Это принимает список файлов для работы как стандартный ввод, а в качестве параметров принимает операцию (например, mv
) и целевой каталог. Как только я это сделаю, я могу делать такие вещи как простой лайнер.
filtercmd () {
if [ ! -d "$2" ]; then echo "$2" does not appear to be a directory; return 1; fi
while read f; do
dir="${f%/*}"
if [ ! "$dir" = "$lastdir" ]
then mkdir -p "$2/$dir"; echo "$dir"; lastdir="$dir"; fi
[ -e "$2/$f" ] || $1 "$f" "$2/$f"; done
}
(cd /media/localbackup && find . | filtercmd "mv -vfb" /media/remotebackup)
Это также можно сделать с помощью rsync
. С помощью rsync
Удаленный протокол может значительно сэкономить полосу пропускания, поскольку протоколу нужно только отправлять измененные фрагменты. Однако два преимущества filtercmd
над rsync
(1) вы можете использовать свои существующие флаги mv без изучения эквивалентов rsync и (2), и мы также можем использовать filtercmd
для более мощных вещей, таких как:
(z(){ grep . <$1|gzip >$2.gz;};find . -name '*.txt' | filtercmd z ../gz })
Что выборочно берет файлы txt, удаляет пустые строки и архивирует их в целевой каталог.
Ваша команда пытается создать уже существующий каталог. Вам следует сделать этот шелл-код более надежным:
tmpdirname=tmpdir
test -d "/media/remotebackup/${tmpdirname}" &&
rm -rf "/media/remotebackup/${tmpdirname}"
pushd /media/localbackup/
test -d "$tmpdirname" && { echo Abbruch; exit 1; }
for dir in *; do
test -d "/media/remotebackup/${dir}" && continue
mv "$dir" "/media/remotebackup/${tmpdirname}" &&
mv "/media/remotebackup/${tmpdirname}" "/media/remotebackup/${dir}"
done
popd
Это пропустит каталоги, которые уже были успешно перемещены.
Я бы использовал команду rsync с параметром --remove-source-files.
Что-то вроде rsync -abv --remove-source-files /media/localbackup/* /media/remotebackup/
Пожалуйста, проверьте, прежде чем применять его в своей среде.