Làm cách nào để đồng bộ hai thư mục với các công cụ dòng lệnh?


63

Đã di chuyển sang Linux từ Windows, tôi muốn tìm một phần mềm thay thế cho Winmerge hoặc tìm hiểu các công cụ dòng lệnh để so sánh và đồng bộ hóa hai thư mục trên Linux. Tôi sẽ biết ơn nếu bạn có thể cho tôi biết cách thực hiện các tác vụ sau trên dòng lệnh ... (Tôi đã nghiên cứu diff và rsync, nhưng tôi vẫn cần một số trợ giúp.)

Chúng tôi có hai thư mục: "/ home / user / A" và "/ home / user / B"

Thư mục A là nơi lưu các tệp và thư mục thông thường và thư mục B là thư mục sao lưu đóng vai trò là bản sao hoàn chỉnh của thư mục A. (Không có gì được người dùng lưu trực tiếp hoặc sửa đổi trong thư mục B.)

Câu hỏi của tôi là:

  • Làm thế nào để liệt kê các tập tin chỉ tồn tại trong thư mục B? (Ví dụ: những cái đã bị xóa khỏi thư mục A kể từ lần đồng bộ hóa cuối cùng.)

  • Làm cách nào để sao chép các tệp tồn tại trong thư mục B trở lại thư mục A?

  • Làm cách nào để liệt kê các tệp tồn tại trong cả hai thư mục nhưng có dấu thời gian hoặc kích thước khác nhau? (Những cái đã được sửa đổi trong thư mục A kể từ lần đồng bộ hóa cuối cùng. Tôi muốn tránh sử dụng tổng kiểm tra, vì có hàng chục ngàn tệp và nó sẽ khiến quá trình này quá chậm.)

  • Làm thế nào để tạo một bản sao chính xác của thư mục A vào thư mục B? Ý tôi là, sao chép mọi thứ từ thư mục A vào thư mục B chỉ tồn tại trong thư mục A và xóa mọi thứ khỏi thư mục B chỉ tồn tại trong thư mục B, nhưng không chạm vào các tệp giống nhau trong cả hai thư mục.


Tại sao không sử dụng một chương trình sao lưu thích hợp cho việc này? Sự trùng lặp là một ví dụ.
Qudit

Câu trả lời:


88

Điều này đặt thư mục A vào thư mục B:

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

Nếu bạn muốn nội dung của các thư mục A và B giống nhau, hãy đặt /home/user/A/(với dấu gạch chéo) làm nguồn. Cái này không lấy thư mục A mà là tất cả nội dung của nó và đặt nó vào thư mục B. Giống như thế này:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Thực hiện đồng bộ hóa bảo toàn tất cả các thuộc tính hệ thống tập tin
  • -v chạy dài dòng
  • -u chỉ sao chép các tệp có thời gian sửa đổi mới hơn (hoặc chênh lệch kích thước nếu thời gian bằng nhau)
  • --delete xóa các tệp trong thư mục đích không tồn tại trong nguồn

Trang chủ: https://doad.samba.org/pub/rsync/rsync.html


7
rsync : chạy ứng dụng rsync, -a : thực hiện đồng bộ hóa bảo toàn tất cả các thuộc tính hệ thống tệp, -v : chạy bằng lời nói, -z : nén dữ liệu trong quá trình đồng bộ hóa (vận chuyển dữ liệu ở chế độ nén), --delete : xóa các tệp trong mục tiêu thư mục không tồn tại trong nguồn, / home / user / A : thư mục nguồn, / home / user / B : thư mục đích
SonicARG

Xin chào SonicARG, tôi hoàn toàn quên mất việc quay lại vấn đề này và đưa ra lời giải thích, nhờ gửi lời giải thích, tôi đặt câu trả lời của bạn, hy vọng bạn không phiền.
TuxForLife

6
Rsync chủ yếu có nghĩa là sao chép các tệp giữa các máy tính khác nhau, như được giải thích ở đây, nó có thể phục vụ mục đích đồng bộ hóa các thư mục. Vì vậy, tùy chọn -z rất thú vị để giảm lưu lượng mạng và do đó nâng cao hiệu suất của rsync giữa 2 máy tính: (đọc dữ liệu từ đĩa -> nén) === mạng ===> (giải nén-> ghi vào đĩa) Sử dụng - z để đồng bộ 2 thư mục trên cùng một máy chủ là một chút ngớ ngẩn và lãng phí chu kỳ cpu như bạn sẽ nhận được (đọc dữ liệu từ đĩa -> nén -> giải nén -> ghi vào đĩa)
GerritCap

@GerritCap, tôi đã thực hiện một chỉnh sửa, cảm ơn về đầu vào có giá trị của bạn
TuxForLife

1
Tôi đã thử lệnh nhưng nó tạo ra một thư mục con /home/user/B/Athay vì ghi đè nội dung của A thành nội dung của B. Bạn có thể giúp tôi có một cái nhìn về nó?
Lu-ca

10

Bạn có thể unisoncông cụ được phát triển bởi Benjamin Pierce tại U Penn.

Giả sử bạn có hai thư mục,

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

Để đồng bộ hóa hai điều này, bạn có thể sử dụng:

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

Trong đầu ra, unisonsẽ hiển thị mỗi và mọi thư mục và tệp khác nhau trong hai thư mục bạn đã yêu cầu đồng bộ hóa. Nó sẽ khuyên bạn nên đồng bộ hóa bổ sung (sao chép tệp bị thiếu ở cả hai vị trí) trong lần chạy ban đầu, sau đó tạo và duy trì cây đồng bộ hóa trên máy của bạn và trong các lần chạy tiếp theo, nó sẽ thực hiện đồng bộ hóa thực sự (nghĩa là nếu bạn xóa một tệp khỏi .../dirAnó cũng sẽ bị xóa khỏi .../dirB. Bạn cũng có thể so sánh từng thay đổi và tùy chọn chọn chuyển tiếp hoặc đảo ngược đồng bộ hóa giữa hai thư mục.

Tùy chọn, để khởi chạy giao diện đồ họa, chỉ cần xóa -ui texttùy chọn khỏi lệnh của bạn, mặc dù tôi thấy cliđơn giản hơn và nhanh hơn để sử dụng.

Thêm về điều này: Unison hướng dẫn tại tài liệu người dùng Unison .


1

Câu trả lời từ TuxForLife là khá tốt, nhưng tôi thực sự khuyên bạn nên sử dụng -ckhi đồng bộ hóa cục bộ. Bạn có thể lập luận rằng nó không đáng để phạt thời gian / mạng để thực hiện điều đó cho đồng bộ hóa từ xa, nhưng nó hoàn toàn xứng đáng với các tệp cục bộ vì tốc độ rất lớn.

-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.

Điều này cho thấy làm thế nào có cùng kích thước và thời gian tem có thể làm bạn thất bại.

Các thiết lập

$ 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 sao chép không có gì vì tất cả các tệp có cùng kích thước và dấu thời gian

$ 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 hoạt động chính xác bởi vì nó so sánh tổng kiểm tra

$ 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 và -u có hoạt động tốt với nhau không?
Serge Korzhov

@SergeyKorzhov thì có. `-U 'vẫn hoạt động như bình thường chỉ cập nhật nếu đích không mới hơn.
Bruno Bronosky

1

Đây là những gì tôi đang sử dụng để sao lưu các tệp cá nhân, nơi tôi không quan tâm đến mọi thứ được đề cập -avà muốn có thêm thông tin hữu ích được in.

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

Từ trang người đàn ông rsync :

-r, --recursive
Điều này cho rsync sao chép các thư mục theo cách đệ quy.

-t, --times
Điều này cho rsync chuyển thời gian sửa đổi cùng với các tệp và cập nhật chúng trên hệ thống từ xa.

-u, --update
Điều này buộc rsync bỏ qua mọi tệp tồn tại trên đích và có thời gian sửa đổi mới hơn tệp nguồn. (Nếu một tệp đích hiện có thời gian sửa đổi bằng với tệp nguồn, nó sẽ được cập nhật nếu kích thước khác nhau.)

--delete
Điều này yêu cầu rsync xóa các tệp không liên quan khỏi phía nhận (những tệp không ở phía gửi), nhưng chỉ cho các thư mục đang được đồng bộ hóa.

--info = FLAGS
Tùy chọn này cho phép bạn có quyền kiểm soát chi tiết đối với đầu ra thông tin bạn muốn xem.

Từ 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)

Mặc dù ít rõ ràng hơn, nhưng điều này dường như tương đương và ngắn hơn:

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

-v, --verbose
Một -v sẽ cung cấp cho bạn thông tin về những tập tin nào đang được chuyển và một bản tóm tắt ngắn gọn ở cuối [stats1].


0

Điều này không hoàn toàn giống như những gì bạn yêu cầu, nhưng bạn có thể cân nhắc sử dụng công cụ kiểm soát phiên bản. Các công cụ như Git làm mọi thứ bạn yêu cầu và hơn thế nữa, đặc biệt là nếu bạn không làm việc trực tiếp trong thư mục B, thật thú vị khi xem qua nó. bạn có thể tìm thêm một số thông tin về git tại đây


2
Điều này chỉ hoạt động nếu bạn sẵn sàng thêm mọi thứ vào kiểm soát phiên bản. Nó cũng buộc mọi thay đổi từng được cam kết sẽ được lưu trữ vĩnh viễn, điều này có thể không mong muốn.
Qudit

@Qudit, điều đó là đúng, mặc dù có thể thông qua nhân bản để giới hạn lịch sử, nhưng giới hạn lịch sử không được (chưa?) Được triển khai trong Git theo mặc định.
chuyển đổi87

@ switch87 Có, tôi biết bạn có thể xóa các xác nhận cũ. Kiểm soát phiên bản không thực sự là một giải pháp thích hợp cho các bản sao lưu chung, đặc biệt là nếu có các tệp nhị phân lớn.
Qudit

Câu hỏi của anh là dành cho sao lưu cục bộ, nhưng nếu bạn sử dụng nó để sao lưu từ xa, bạn vẫn có thể sử dụng git annex cho các tệp lớn hơn. để sao lưu cục bộ, đây không phải là vấn đề.
switch87

2
@ switch87 Đây thực sự nên là một bình luận cho Q và không phải là một câu trả lời vì nó không giải thích cách bạn sử dụng git để sao lưu.
slm

0

Bạn có thể sử dụng nó theo cách này:

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

Bằng cách này, bạn sẽ sao chép nội dung của thư mục A vào thư mục B, chứ không phải nội dung của chính thư mục A.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.