将文件从一个设备移动到另一个设备

将文件从一个设备移动到另一个设备

我正在尝试在我们的 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,但是这不会随后删除文件,我需要在成功备份后删除文件。

答案1

我还建议您使用rsync而不是mv,但要添加到@Hartmut 的回答

rsync -abmv --remove-source-files /media/localbackup /media/remotebackup/
find /media/localbackup -depth -type d -empty -delete

这里补充 2 点:

  1. -m的( --prune-empty-dirs) 参数,rsync在我的版本 3.0.7 协议版本 30 中表示:从文件列表中删除空目录链,但由于某种原因没有这样做。也没有错误(并非唯一注意到这一点的人)。
  2. find命令将删除空目录。

现在,原因是反对 cp&&rmcp可能会中途失败。下次您想要备份时,您将遇到一种奇怪的情况(部分复制文件是最糟糕的情况)。此外,下一次备份将不知道如何处理之前备份的未删除的文件。另一方面,rsync很好地涵盖了这些方面。

此外,使用脚本(如第一个答案所建议的)来执行 rsync 已经执行的操作(但更糟糕的是,这是行不通的(对不起 Hauke Laging :-) )。这里不需要重新发明轮子。

答案2

我发现我经常想对文件进行一些操作,同时保留它们的目录结构。为此,我定义了一个 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( rsync1) 您可以使用现有的 mv 标志,而无需学习 rsync 等效项;(2) 我们还可以将其用于filtercmd更强大的功能,例如:

(z(){ grep . <$1|gzip >$2.gz;};find . -name '*.txt' | filtercmd z ../gz })

它有选择地获取 txt 文件,删除空行,然后将其通过 gzip 压缩到目标目录中。

答案3

您的命令尝试创建一个已经存在的目录。您应该使此 shell 代码更加健壮:

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

这将跳过已经成功移动的目录。

答案4

我将使用带有 --remove-source-files 选项的 rsync 命令。

就像是rsync -abv --remove-source-files /media/localbackup/* /media/remotebackup/

在将其应用到您的环境之前,请先进行测试。

相关内容