Bagaimana cara menyinkronkan dua folder dengan alat baris perintah?

63

Setelah bermigrasi ke Linux dari Windows, saya ingin mencari perangkat lunak alternatif untuk Winmerge atau lebih tepatnya mempelajari alat-alat baris perintah untuk membandingkan dan menyinkronkan dua folder di Linux. Saya akan berterima kasih jika Anda bisa memberi tahu saya bagaimana melakukan tugas-tugas berikut pada baris perintah ... (Saya telah mempelajari diff dan rsync, tapi saya masih butuh bantuan.)

Kami memiliki dua folder: "/ home / user / A" dan "/ home / user / B"

Folder A adalah tempat penyimpanan file dan folder biasa dan folder B adalah folder cadangan yang berfungsi sebagai cermin lengkap folder A. (Tidak ada yang langsung disimpan atau diubah oleh pengguna di folder B.)

Pertanyaan saya adalah:

  • Bagaimana daftar file yang hanya ada di folder B? (Misalnya yang dihapus dari folder A sejak sinkronisasi terakhir.)

  • Bagaimana cara menyalin file yang ada di folder B saja kembali ke folder A?

  • Bagaimana cara membuat daftar file yang ada di kedua folder tetapi memiliki cap waktu atau ukuran yang berbeda? (Yang telah dimodifikasi di folder A sejak sinkronisasi terakhir. Saya ingin menghindari menggunakan checksum, karena ada puluhan ribu file dan itu akan membuat prosesnya terlalu lambat.)

  • Bagaimana cara membuat salinan folder A ke dalam folder B? Maksud saya, salin semuanya dari folder A ke folder B yang hanya ada di folder A dan hapus semuanya dari folder B yang hanya ada di folder B, tetapi tanpa menyentuh file yang sama di kedua folder.

akopacsi
sumber
Mengapa tidak menggunakan program cadangan yang tepat untuk ini? Duplicity adalah salah satu contohnya.
Qudit

Jawaban:

88

Ini menempatkan folder A ke folder B:

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

Jika Anda ingin isi folder A dan B sama, masukkan /home/user/A/(dengan garis miring) sebagai sumber. Ini tidak mengambil folder A tetapi semua kontennya dan memasukkannya ke folder B. Seperti ini:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Lakukan sinkronisasi menjaga semua atribut sistem file
  • -v berjalan secara lisan
  • -u hanya menyalin file dengan waktu modifikasi yang lebih baru (atau perbedaan ukuran jika waktunya sama)
  • --delete hapus file di folder target yang tidak ada di sumber

Manpage: https://download.samba.org/pub/rsync/rsync.html

TuxForLife
sumber
7
rsync : jalankan aplikasi rsync, -a : lakukan sinkronisasi yang melestarikan semua atribut sistem file, -v : jalankan secara verbal, -z : kompres data selama sinkronisasi (transport data dalam mode terkompresi), --delete : hapus file dalam target folder yang tidak ada di sumber, / home / user / A : folder sumber, / home / user / B : folder target
SonicARG
Hai SonicARG, saya benar-benar lupa untuk kembali ke sini dan memberikan penjelasan, terima kasih mengirimkan penjelasan, saya berikan jawaban Anda, harap Anda tidak keberatan.
TuxForLife
6
Rsync terutama dimaksudkan untuk menyalin file antara komputer yang berbeda, seperti yang dijelaskan di sini dapat melayani tujuan untuk menyinkronkan direktori juga. Jadi opsi -z menarik untuk mengurangi lalu lintas jaringan dan dengan demikian meningkatkan kinerja rsync antara 2 komputer: (baca data dari disk -> kompres) === jaringan ===> (uncompress-> tulis ke disk) Menggunakan - z untuk menyinkronkan 2 direktori pada host yang sama agak konyol dan membuang siklus cpu seperti yang Anda dapatkan (baca data dari disk -> kompres -> uncompress -> tulis ke disk)
GerritCap
@GerritCap, saya mengedit, terima kasih atas masukan Anda yang berharga
TuxForLife
1
Saya sudah mencoba perintah tetapi membuat sub-dir /home/user/B/Aalih - alih menimpa konten A ke konten B. Bisakah Anda membantu saya memeriksanya?
Luke
10

Anda dapat menggunakan unisonalat yang dikembangkan oleh Benjamin Pierce di U Penn.

Mari kita asumsikan Anda memiliki dua direktori,

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

Untuk menyinkronkan keduanya, Anda dapat menggunakan:

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

Dalam output, unisonakan ditampilkan setiap direktori dan file yang berbeda di dua direktori yang Anda minta untuk disinkronkan. Ini akan merekomendasikan untuk menyinkronkan secara aditif (mereplikasi file yang hilang di kedua lokasi) pada proses awal, kemudian membuat dan memelihara pohon sinkronisasi pada mesin Anda, dan pada proses selanjutnya akan menerapkan sinkronisasi yang benar (yaitu, jika Anda menghapus file dari .../dirA, itu akan dihapus .../dirBjuga. Anda juga dapat membandingkan setiap perubahan dan secara opsional memilih untuk meneruskan atau membalikkan sinkronisasi antara dua direktori.

Secara opsional, untuk meluncurkan antarmuka grafis, cukup hapus -ui textopsi dari perintah Anda, meskipun saya menemukan clilebih sederhana dan lebih cepat untuk digunakan.

Lebih lanjut tentang ini: Tutorial serempak di dokumentasi pengguna Unison .

Aalok
sumber
1

Jawaban dari TuxForLife cukup bagus, tetapi saya sangat menyarankan Anda gunakan -csaat menyinkronkan secara lokal. Anda dapat berargumen bahwa tidak sepadan dengan waktu / penalti jaringan untuk melakukannya untuk sinkronisasi jarak jauh, tetapi sangat layak untuk file lokal karena kecepatannya sangat besar.

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

Ini menunjukkan bagaimana memiliki ukuran dan waktu yang sama dapat membuat Anda gagal.

Pengaturan

$ 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 yang tidak menyalin apa pun karena semua file memiliki ukuran dan stempel waktu yang sama

$ 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 yang berfungsi dengan benar karena membandingkan checksum

$ 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
Bruno Bronosky
sumber
apakah -c dan -u bekerja dengan baik bersama?
Sergey Korzhov
@SergeyKorzhov tidak. `-U 'masih berfungsi seperti biasa untuk memperbarui hanya jika tujuan tidak lebih baru.
Bruno Bronosky
1

Ini adalah apa yang saya gunakan untuk membuat cadangan file pribadi, di mana saya tidak peduli dengan semua yang dicakup -a, dan ingin informasi yang lebih berguna dicetak.

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

Dari halaman manual rsync :

-r, --recursive
Ini memberitahu rsync untuk menyalin direktori secara rekursif.

-t, --times
Ini memberitahu rsync untuk mentransfer waktu modifikasi bersama dengan file dan memperbaruinya pada sistem jarak jauh.

-u, --update
Ini memaksa rsync untuk melewatkan file apa pun yang ada di tujuan dan memiliki waktu modifikasi yang lebih baru dari file sumber. (Jika file tujuan yang ada memiliki waktu modifikasi sama dengan file sumber, itu akan diperbarui jika ukurannya berbeda.)

--delete
Ini memberitahu rsync untuk menghapus file asing dari sisi penerima (yang tidak ada di sisi pengirim), tetapi hanya untuk direktori yang sedang disinkronkan.

--info = BENDERA
Opsi ini memungkinkan Anda memiliki kendali yang baik atas keluaran informasi yang ingin Anda lihat.

Dari 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)

Meskipun kurang eksplisit, ini tampaknya setara dan lebih pendek:

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

-v, --verbose
Satu -v akan memberi Anda informasi tentang file apa yang sedang ditransfer dan ringkasan singkat di akhir [stats1].

Abe Jujur
sumber
0

Ini tidak sepenuhnya sama dengan apa yang Anda minta, tetapi Anda dapat mempertimbangkan menggunakan alat kontrol versi. Alat-alat seperti Git melakukan semua yang Anda minta, dan banyak lagi, terutama jika Anda tidak bekerja di folder B secara langsung, mungkin menarik untuk melihatnya. Anda dapat menemukan informasi lebih lanjut tentang git di sini

saklar87
sumber
2
Ini hanya berfungsi jika Anda ingin menambahkan semuanya ke kontrol versi. Itu juga memaksa setiap perubahan yang pernah dilakukan untuk disimpan secara permanen, yang mungkin tidak diinginkan.
Qudit
@Qudit, itu benar, meskipun dimungkinkan melalui kloning untuk membatasi histori, tetapi membatasi histori tidak (belum?) Diimplementasikan di Git secara default.
switch87
@ switch87 Ya, saya tahu Anda dapat menghapus commit lama. Kontrol versi bukanlah solusi tepat untuk pencadangan generik, terutama jika ada file biner yang besar.
Qudit
Pertanyaannya adalah untuk pencadangan lokal, tetapi jika Anda menggunakannya untuk pencadangan jarak jauh Anda masih dapat menggunakan lampiran git untuk file yang lebih besar. untuk cadangan lokal ini bukan masalah.
switch87
2
@ switch87 Ini seharusnya sudah menjadi komentar untuk Q dan bukan jawaban karena tidak menjelaskan bagaimana Anda akan menggunakan git untuk melakukan backup.
slm
0

Anda dapat menggunakannya dengan cara ini:

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

Dengan cara ini Anda akan menyalin konten folder A ke folder B, bukan konten folder A itu sendiri.

Isaias Sanchez
sumber