【问题标题】:Rsync backup one source directory and check agains multiple directoriesrsync 备份一个源目录并检查多个目录
【发布时间】:2017-01-16 11:24:27
【问题描述】:

我正在尝试将“sdir”目录复制(rsync)到 tdir 目录,具体取决于日期。我想要一份完整的副本到 mon 目录,周二只有更改的内容,婚礼只有更改的内容,等等,但我没有得到我需要的结果。 参考我运行的实际命令:

[jesse@localhost test]$ tree
.
├── sdir
│   ├── file1
│   ├── file2
│   ├── file3
│   ├── file4
│   └── file5
└── tdir
    ├── fri
    ├── mon
    │   ├── file1
    │   └── file2
    ├── thu
    ├── tue
    │   └── file3
    └── wed
        ├── file3
        ├── file4
        └── file5

7 directories, 11 files
[jesse@localhost test]$ touch sdir/file6
[jesse@localhost test]$ rsync -av --dry-run sdir/ --compare-dest=/home/jesse/test/tdir/mon/ /home/jesse/test/tdir/tue/ /home/jesse/test/tdir/wed/ /home/jesse/test/tdir//thu/ --backup-dir=/home/jesse/test/tdir/fri/
sending incremental file list
./
file3
file4
file5
file6

sent 294 bytes  received 31 bytes  650.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[jesse@localhost test]$ rsync -av --dry-run sdir/ --compare-dest=/home/jesse/test/tdir/mon/ /home/jesse/test/tdir/tue/ /home/jesse/test/tdir/wed/ /home/jesse/test/tdir//thu/ --backup-dir=/home/jesse/test/tdir/thu/
sending incremental file list
./
file3
file4
file5
file6

sent 294 bytes  received 31 bytes  650.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[jesse@localhost test]$ rsync -av --dry-run sdir/ --compare-dest=/home/jesse/test/tdir/mon/ /home/jesse/test/tdir/tue/ /home/jesse/test/tdir/wed/ --backup-dir=/home/jesse/test/tdir/thu/
sending incremental file list
./
file6

sent 208 bytes  received 22 bytes  460.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[jesse@localhost test]$ rsync -av --dry-run sdir/ --compare-dest=/home/jesse/test/tdir/mon/ /home/jesse/test/tdir/tue/ /home/jesse/test/tdir/wed/ /home/jesse/test/tdir/thu/ --backup-dir=/home/jesse/test/tdir/thu/
sending incremental file list
./
file3
file4
file5
file6

sent 294 bytes  received 31 bytes  650.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[jesse@localhost test]$ rsync -av  sdir/ --compare-dest=/home/jesse/test/tdir/mon/ /home/jesse/test/tdir/tue/ /home/jesse/test/tdir/wed/ /home/jesse/test/tdir/thu/ --backup-dir=/home/jesse/test/tdir/thu/
sending incremental file list
./
file3
file4
file5
file6

sent 438 bytes  received 95 bytes  1,066.00 bytes/sec
total size is 0  speedup is 0.00
[jesse@localhost test]$ tree
.
├── sdir
│   ├── file1
│   ├── file2
│   ├── file3
│   ├── file4
│   ├── file5
│   └── file6
└── tdir
    ├── fri
    ├── mon
    │   ├── file1
    │   └── file2
    ├── thu
    │   ├── file3
    │   ├── file4
    │   ├── file5
    │   └── file6
    ├── tue
    │   └── file3
    └── wed
        ├── file3
        ├── file4
        └── file5

7 directories, 16 files
[jesse@localhost test]$ 

【问题讨论】:

  • 您确定--backup-dir 是您想要的方式吗?我更相信--link-dest,因此每个备份都是完全可用的,相同的文件与之前的备份硬链接。也就是说,使用--itemize-changes (-i) 选项探索您所看到的内容。如果这确实是问题所在,可能会帮助您了解导致比较失败的原因。
  • 你为什么要问 --backup-dir 是否可行?是不是很糟糕...在使用 --dry-run 而没有 --dry-run 时,我确实看到备份开关的结果不一致。使用 --dry-run,它会为我提供要更新的正确文件,但如果没有 --dry-run,它将复制自原始备份以来更改的所有内容。
  • 当我运行rsync source mon 命令时,rsync 工作正常。它也适用于rsync source mon tue,但不是当我运行rsync source --compare-dest=mon tue wed 时,这会中断并给我自周一以来发生的所有变化,并进入周三。使用 --backup-dir 似乎给了我正确的结果 --dry-run 但是当我在没有它的情况下运行它时,它会做同样的事情。

标签: bash rsync


【解决方案1】:

我注意到 rsync 手册页明确指出“从版本 2.6.4 开始,可以提供多个 --link-dest 目录”,--compare-dest 也有类似的说明,但不适用于--backup-dir(这是有道理的)。如果您想将备份限制为“仅不在多个其他目录之一中的内容”,则可以使用--*-dest 选项。

这是我的测试和结果:

$ mkdir src mon tue wed
$ for n in {1..3}; do date > src/file$n; sleep 1; done
$ rsync -avi src/ mon/
building file list ... done
.d..t.... ./
>f+++++++ file1
>f+++++++ file2
>f+++++++ file3

sent 346 bytes  received 92 bytes  876.00 bytes/sec
total size is 87  speedup is 0.20
$ for n in {4..5}; do date > src/file$n; sleep 1; done
$ rsync -avi --compare-dest=$PWD/mon/ src/ tue/
building file list ... done
.d..t.... ./
>f+++++++ file4
>f+++++++ file5

sent 295 bytes  received 70 bytes  730.00 bytes/sec
total size is 145  speedup is 0.40
$ for n in {6..7}; do date > src/file$n; sleep 1; done
$ rsync -avi --compare-dest=$PWD/mon/ --compare-dest=$PWD/tue/ src/ wed/
building file list ... done
.d..t.... ./
>f+++++++ file6
>f+++++++ file7

sent 319 bytes  received 70 bytes  778.00 bytes/sec
total size is 203  speedup is 0.52
$

这里的显着区别是每个比较目录都需要自己的选项。符号不是:

rsync --compare-dest one/ two/ src/ dest/

而是:

rsync --compare-dest=one/ --compare-dest=two/ src/ dest/

要将其放入每天运行的代码中,您可以尝试如下(未经测试的脚本):

#!/usr/bin/env bash

# Store our rsync arguments in an array, for easier handling.
rsync_args=(-a)

# If we're running interactively, show us rsync verbose output.
if [ -t 0 ]; then
  rsync_args+=(-vi)
fi

# Step through weekdays, adding days to our argument list, stopping at "today"
read today < <(date '+%a')
for day in Mon Tue Wed Thu Fri; do
  [ "$day" = "$today" ] && break
  rsync_args+=(--compare-dest=$PWD/${day,,})
done

# And finally, copy everything.
rsync "${rsync_args[@]}" src/ "${day,,}"/

请注意,bash 在参数扩展中的大小写控制(${s,,}${s^^})是 bash 版本 4 的功能。

【讨论】:

  • 谢谢。这正是我想做的。你是个天才先生。还有一个问题。我注意到没有更改的目录被复制到没有文件的目标,这是有道理的,但是有没有办法防止在目标创建目录名称。
  • 很高兴我能帮上忙!如果此答案似乎可以为您解决问题,请随时通过单击答案左侧的复选标记将问题标记为已关闭。 :-) 至于跳过空目录,我从 rsync 的手册页中看到有一个 --prune-empty-dirs 选项可供您试验。
  • 感谢您的回复。我确实看到了该选项,但我希望 rsync 跳过的目录是最新的并且没有任何要更新的目录。换句话说,我想避免在一个目录中仅更改一个文件时创建整个层次结构。我只希望那些包含要在目标上创建的文件的目录。这是我应该在 stackoverflow 上发布的新问题吗?
  • 嗯。所以您希望--compare-dest 跳过未更改的目录,而不是在目标上创建目录层次结构?我不确定这是否可能,因为我认为--compare-dest 只作用于文件,但我也不确定我是否100% 理解这一点,这让我认为an example将是有序的,这可能意味着一个新问题。这种事情也有可能成为StackOverflow Documentation的候选对象。
  • 是的,我只希望包含更新文件的目录备份到目的地。如果我在源上有:dir1/d1file1 和 dir2/d2file1 .....现在我修改/更新 dir1/d1file1 上的内容......现在我 rsync,我只想要目标上的 dir1/d1file1 ......但我我得到 dir1/d1file1 和 dir2(但它是空的,它应该是空的,这是我想要阻止的,这个目录不应该在目标上)。我会发布新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 2013-11-02
  • 2015-11-03
  • 2015-01-14
  • 2015-06-13
相关资源
最近更新 更多