Bagaimana saya bisa menggunakan rsync untuk menduplikasi pohon direktori, membuat hardlink ke file?

23

Dari waktu ke waktu, saya harus melakukan beberapa perubahan migrasi besar pada file data di server saya, dan saya sedang mencari cara yang baik untuk melakukan ini. Saya sedang berpikir tentang menggunakan rsync untuk menduplikasi struktur direktori saya mulai dari folder data root, membuat tautan keras ke semua file asli (beberapa di antaranya agak besar), dan saya bisa menimpa di pohon tujuan hanya file yang perlu dimigrasi. Pada akhirnya, saya dapat dengan aman beralih dari file lama ke file baru dengan dua mvoperasi.

Namun, sepertinya saya tidak bisa mendapatkan rsync untuk melakukan ini. Saya mencoba

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

tetapi alih-alih membuat tautan keras ke file, rsync menyalinnya seluruhnya. Apakah ada masalah menggunakan direktori source dan link-dest yang sama?

Jean-Philippe Pellet
sumber

Jawaban:

21

rsync adalah alat yang ampuh, tetapi, sayangnya, pilih-pilih aneh tentang beberapa nama pathnya.

Jika $DATApath absolut (yaitu dimulai dengan a /), maka baris perintah yang benar untuk digunakan adalah:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[Sekarang, hanya kesampingkan tentang rsynckeanehan. Perhatikan trailing yang /ditambahkan ke argumen sumber. Ini memberitahu rsyncuntuk bekerja dengan isi direktori sumber, bukan dengan direktori sumber itu sendiri. (Saya berasumsi itu $DATAbelum mengandung trailing /.) Dalam hal ini, kami ingin bekerja dengan konten, jadi kami menambahkan trailing /.]

Sebaliknya, jika $DATA adalah jalur relatif (yaitu tidak dimulai dengan a /), maka komentar Sean R tentang --link-destbang on: Jalur tautan-dest ditafsirkan relatif terhadap jalur tujuan , sehingga Anda akan menggunakan yang berikut:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

EDIT

Satu catatan terakhir, ternyata yang kedua rsync baris perintah saya berikan harus berfungsi terlepas dari apakah $DATAjalur absolut, karena basenametidak peduli apakah jalur absolut atau relatif.

Steven Monday
sumber
1
Hanya tebasan yang hilang, siapa yang akan memikirkan itu ... Terima kasih atas penjelasan yang bagus!
Jean-Philippe Pellet
Terima kasih untuk ini, saya mencoba mengikuti beberapa petunjuk cadangan tambahan, seperti ini dan tidak menemukan menyebutkan kekhasan ini. Ini adalah satu-satunya hal yang benar-benar memastikan file sedang di-hardlink. Memeriksa bahwa penghitungan ref> 1 dan nomor inode sama denganls -ilah
Walf
Saya menggunakan ini bersamaan dengan fungsi relpath () yang dijelaskan di unix.stackexchange.com/a/85068/57414 untuk membuat cadangan $SOURCEdirektori ke $TARGETdir seperti ini:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh
13

Yang Anda inginkan adalah "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • seperti berulang rsync -a
  • -l akan menautkan file bukan menyalinnya.
Sean Reifschneider
sumber
1
cp -alsayangnya tidak tersedia di sistem saya (Mac OS X 10.6). Saya akan menggunakan pax sebagai gantinya ...
Jean-Philippe Pellet
7

The --link-destpilihan di rsyncrelatif ke tujuan direktori, bukan direktori saat ini. Jadi yang Anda inginkan adalah:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp
Sean Reifschneider
sumber
Ups, maksudku nama kecil, awalnya aku punya dirname.
Sean Reifschneider
1
Halaman manual mengatakan bahwa --link-destopsi, jika relatif , relatif terhadap direktori target. Dalam kasus saya ini mutlak. Bahkan membuatnya relatif ke direktori target tidak membuat ini berfungsi.
Jean-Philippe Pellet
7

Ternyata lebih sulit melakukan ini rsyncdibandingkan dengan alat lain. Jawaban yang benar rsyncadalah untuk Steven Monai, tetapi cara termudah untuk melakukan ini adalah dengan menggunakan salah satu cp -alatau pax -rwlpada sistem -lyang bukan pilihan yang valid untuk cp:

pax -rwl $DATA $DATA/../upgrade_tmp

atau

cp -al $DATA/ $DATA/../upgrade_tmp/
Jean-Philippe Pellet
sumber
4

Ini bekerja untuk saya:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

Saya menggunakan rsync versi 3.1.0.

Dari manusia :

--hard-link

Memberitahu rsync untuk mencari file yang terhubung dengan keras dalam transfer, tanpa opsi ini, file yang terhubung dengan keras dalam transfer diperlakukan seolah-olah mereka adalah file yang terpisah.

--link-dest = DIR

File yang tidak diubah sulit ditautkan dari DIR ke direktori tujuan. File-file harus identik dalam semua atribut yang dipertahankan (mis. Izin, kemungkinan kepemilikan) agar file-file tersebut dihubungkan bersama

Alexander Fedorov
sumber
2
Hanya potongan kode tidak cukup, jelaskan apa yang dilakukannya dan mengapa.
peterh mengatakan mengembalikan Monica
--hard-links Memberitahu rsync untuk mencari file yang terhubung dengan keras dalam transfer, tanpa opsi ini, file yang terhubung dengan keras dalam transfer diperlakukan seolah-olah mereka adalah file yang terpisah. --link-dest = DIR File yang tidak diubah sulit ditautkan dari DIR ke direktori tujuan. File-file harus identik dalam semua atribut yang dipertahankan (mis. Izin, kemungkinan kepemilikan) agar file-file tersebut dihubungkan bersama.
Alexander Fedorov
1
Hebat. Terima kasih. Sebenarnya, saya menemukan jawaban Anda dalam antrian "kualitas rendah". Artinya, ada suara apakah jawaban Anda harus dihapus atau tidak. Tetapi tidak hanya bahaya dari penghapusan adalah alasan untuk mencoba memberikan jawaban, "manusia" yang diformat dengan baik, tetapi juga banyak membantu jika Anda ingin mengumpulkan upvotes.
peterh mengatakan mengembalikan Monica
2

Dapat mencoba tautan berikut http://www.lessfs.com/wordpress/ ini berfungsi pada COW (copy on write) yang akan menghemat waktu dan ruang

Rajat
sumber
lessfs sangat menarik, tetapi juga sangat eksperimental. Belum direkomendasikan untuk penggunaan produksi.
mattdm
2

Pertama buat direktori hanya pada tujuan:

rsync -av --include '*/' --exclude '*' /source/ /destination/

Maka hanya menautkan file:

cd /source
find . -type f -exec ln -v {} /destination/{} \;
Cakemox
sumber
Terima kasih - sebenarnya, saya mungkin juga menggunakan paxseperti yang ditunjukkan dalam komentar saya di atas, yang tampaknya lebih mudah.
Jean-Philippe Pellet
1

Gunakan Opsi -H untuk melestarikan Hardlink dan membaca halaman manual.

tex
sumber
1
- Dia tidak bekerja. Saya tidak memiliki hardlink untuk disimpan di pohon sumber saya, saya hanya ingin salinan sederhana dari pohon sumber saya di mana dalam salinan, semua file di-hardlink ke file asli. Maaf dalam pertanyaan awal saya tidak jelas ...
Jean-Philippe Pellet
Apakah "baca halaman manual" merupakan jawaban? :-)
meduz