如何使用命令行工具同步两个文件夹?


63

从Windows迁移到Linux之后,我想找到Winmerge的替代软件,或者想学习命令行工具来比较和同步Linux上的两个文件夹。如果您能告诉我如何在命令行上执行以下任务,我将不胜感激...(我研究过diff和rsync,但我仍然需要一些帮助。)

我们有两个文件夹:“ / home / user / A”和“ / home / user / B”

文件夹A是保存常规文件和文件夹的位置,文件夹B是充当文件夹A完整镜像的备份文件夹。(用户在文件夹B中没有直接保存或修改的内容。)

我的问题是:

  • 如何列出仅存在于文件夹B中的文件?(例如,自上次同步以来从文件夹A中删除的文件。)

  • 如何将仅存在于文件夹B中的文件复制回文件夹A中?

  • 如何列出两个文件夹中都存在但具有不同时间戳或大小的文件?(自上次同步以来已在文件夹A中进行过修改的文件。我想避免使用校验和,因为有成千上万个文件,这会使处理速度太慢。)

  • 如何将文件夹A的精确副本复制到文件夹B中?我的意思是,将文件夹A中的所有内容复制到仅存在于文件夹A中的文件夹B中,并将文件夹B中仅存在于文件夹B中的所有内容删除,但不要触摸两个文件夹中相同的文件。


为什么不为此使用适当的备份程序?重复性就是一个例子。
Qudit

Answers:


88

这会将文件夹A放入文件夹B:

rsync -avu --delete "/home/user/A" "/home/user/B"  

如果希望文件夹A和B内容相同,则将其/home/user/A/(带有斜线)作为源。这不占用文件夹A,而是所有内容,并将其放入文件夹B。像这样:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a 进行同步以保留所有文件系统属性
  • -v 冗长地跑
  • -u 仅复制修改时间较新的文件(如果时间相等,则复制大小不同的文件)
  • --delete 删除目标文件夹中源文件中不存在的文件

手册页:https : //download.samba.org/pub/rsync/rsync.html


7
rsync的:运行rsync的应用程序,-a:做同步保存所有文件系统的属性,-v:冗长运行,-z:在同步过程中压缩数据(传输压缩模式的数据),--delete:删除目标文件源文件夹中不存在的文件夹,/ home / user / A:源文件夹,/ home / user / B:目标文件夹
SonicARG

嗨,SonicARG,我完全忘了回头再解释,谢谢您提交解释,我把您的回答告诉我们,希望您不要介意。
TuxForLife

6
Rsync的主要目的是在不同计算机之间复制文件,如此处所述,它也可以用于同步目录。因此,-z选项很有趣,可以减少网络流量,从而提高两台计算机之间的rsync性能:(从磁盘读取数据->压缩)=== network ===>(解压缩->写入磁盘)使用- z同步同一主机上的2个目录有点愚蠢,并且会浪费CPU周期(从磁盘读取数据->压缩->解压缩->写入磁盘)
GerritCap

@GerritCap,我进行了编辑,感谢您的宝贵意见
TuxForLife

1
我已经尝试过该命令,但是它创建了一个子目录,/home/user/B/A而不是将A的内容覆盖为B的内容。你能帮我看看吗?
路加福音

10

您可以使用unisonU Penn的Benjamin Pierce开发的工具。

让我们假设您有两个目录,

/home/user/Documents/dirA//home/user/Documents/dirB/

要同步这两个,可以使用:

〜$unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

在输出中,unison将显示您要求同步的两个目录中每个不同的目录和文件。建议在初次运行时进行附加同步(在两个位置都复制丢失的文件),然后在计算机上创建并维护一个同步树,在以后的运行中它将实现真正的同步(即,如果从中删除文件.../dirA,将得到删除.../dirB为好。你也可以比较每一个变化和可选选择转发反转的两个目录之间同步。

(可选)要启动图形界面,只需-ui text从命令中删除该选项,尽管我发现使用起来cli更简单,更快捷。

有关更多信息:Unison用户文档上的Unison教程


1

TuxForLife的答案很好,但我强烈建议您-c在本地同步时使用。您可以辩解说,为远程同步这样做不值得花费时间/网络代价,但是对于本地文件来说完全值得,因为速度是如此之快。

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

这显示了具有相同大小和时间戳的方法会使您失败。

设置

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

rsync不复制任何内容,因为文件都具有相同的大小和时间戳

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

正确工作的rsync,因为它比较校验和

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b

-c和-u一起工作是否很好?
谢尔盖·科尔佐夫

@SergeyKorzhov确实如此。仅当目标位置不是较新时,“-u”仍将照常工作以进行更新。
布鲁诺·布鲁诺斯基

1

这就是我用来备份个人文件的方式,我不在乎所涉及的所有内容-a,而是希望打印出更多有用的信息。

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

rsync手册页

-r,--
recursive这告诉rsync递归复制目录。

-t,--
times这告诉rsync将修改时间与文件一起传输并在远程系统上更新它们。

-u,--update
这将强制rsync跳过目标上存在的且具有比源文件新的修改时间的所有文件。(如果现有目标文件的修改时间与源文件的修改时间相等,则如果大小不同,它将被更新。)

--delete
这告诉rsync从接收方删除无关的文件(不在发送方的文件),但仅针对正在同步的目录。

--info = FLAGS
此选项使您可以对想要查看的信息输出进行细粒度控制。

rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

虽然不太明确,但这似乎等效且较短:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v,--verbose
单个-v将为您提供有关正在传输哪些文件的信息,并在末尾提供简要摘要[stats1]。


0

这与您要求的不完全相同,但是您可以考虑使用版本控制工具。诸如Git之类的工具可以满足您的所有需求,尤其是如果您不直接在文件夹B中工作时,看看它可能会很有趣。您可以在此处找到有关git的更多信息


2
这仅在您愿意将所有内容添加到版本控制中时才有效。它还会强制将曾经承诺的所有更改永久存储,这可能是不希望的。
Qudit

@Qudit,这是正确的,尽管可以通过克隆来限制历史记录,但是默认情况下,尚未(在?中)限制历史记录。
switch87

@ switch87是的,我知道您可以删除旧的提交。但是,版本控制并不是真正适用于通用备份imo的合适解决方案,尤其是在存在大型二进制文件的情况下。
2015年

他的问题是本地备份,但是如果将其用于远程备份,仍然可以使用git annex来存储较大的文件。对于本地备份,这不是问题。
switch87

2
@ switch87这确实应该是对Q的注释,而不是答案,因为它没有解释如何使用git进行备份。
slm

0

您可以通过以下方式使用它:

rsync -avu --delete /home/user/A/* /home/user/B/

这样,您会将文件夹A的内容复制到文件夹B,而不是文件夹A本身的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.