perintah cp: salin folder file dengan benar ke * nix

perintah cp: salin folder file dengan benar ke * nix

Artikel ini akan mengungkap beberapa hal yang tidak jelas terkait penggunaan wildcard saat menyalin, perilaku perintah ambigu cp saat menyalin, serta metode yang memungkinkan Anda menyalin sejumlah besar file dengan benar tanpa melewatkan atau mogok.

Katakanlah kita perlu menyalin semuanya dari folder /source ke folder /target.

Hal pertama yang terlintas dalam pikiran adalah:

cp /source/* /target

Mari kita segera perbaiki perintah ini menjadi:

cp -a /source/* /target

ΠšΠ»ΡŽΡ‡ -a akan menambahkan penyalinan semua atribut, hak dan menambahkan rekursi. Jika reproduksi hak yang sebenarnya tidak diperlukan, maka kunci saja sudah cukup -r.

Setelah menyalin, kita akan menemukan bahwa tidak semua file disalin - file dimulai dengan titik seperti:

.profile
.local
.mc

dan sejenisnya.

Kenapa ini terjadi?

Karena wildcard diproses oleh shell (bash dalam kasus yang khas). Secara default, bash akan mengabaikan semua file yang dimulai dengan titik, karena menganggap file tersebut tersembunyi. Untuk menghindari perilaku ini kita harus mengubah perilaku bash menggunakan perintah:

shopt -s dotglob

Untuk memastikan bahwa perubahan perilaku ini tetap ada setelah reboot, Anda dapat membuat file wildcard.sh dengan perintah ini di folder /etc/profile.d (Mungkin distribusi Anda memiliki folder lain).

Dan jika tidak ada file di direktori sumber, maka shell tidak akan dapat menggantikan apa pun sebagai pengganti tanda bintang, dan penyalinan juga akan gagal karena kesalahan. Ada beberapa pilihan untuk mengatasi situasi ini failglob ΠΈ nullglob. Kita perlu mengaturnya failglob, yang akan mencegah perintah dijalankan. nullglob tidak akan berfungsi, karena ini mengubah string dengan wildcard yang tidak menemukan kecocokan menjadi string kosong (panjang nol), yang mana cp akan menyebabkan kesalahan.

Namun, jika ada ribuan file atau lebih dalam folder tersebut, maka pendekatan wildcard harus ditinggalkan sama sekali. Faktanya adalah itu bash memperluas wildcard menjadi baris perintah yang sangat panjang seperti:

cp -a /souce/a /source/b /source/c …… /target

Ada batasan panjang baris perintah, yang bisa kita ketahui dengan menggunakan perintah:

getconf ARG_MAX

Mari kita dapatkan panjang maksimum baris perintah dalam byte:

2097152

Или:

xargs --show-limits

Kami mendapatkan sesuatu seperti:

….
Maximum length of command we could actually use: 2089314
….

Jadi, mari kita lakukan tanpa wildcard sama sekali.

Mari kita menulis saja

cp -a /source /target

Dan di sini kita dihadapkan pada ambiguitas perilaku cp. Jika folder /target tidak ada, maka kita akan mendapatkan apa yang kita butuhkan.

Namun jika folder target ada, maka file akan disalin ke folder /target/source.

Kami tidak selalu dapat menghapus folder /target terlebih dahulu, karena folder tersebut mungkin berisi file yang kami perlukan dan tujuan kami, misalnya, adalah melengkapi file di /target dengan file dari /source.

Jika folder sumber dan tujuan diberi nama yang sama, misalnya kita menyalin dari /source ke /home/source, maka kita dapat menggunakan perintah:

cp -a /source /home

Dan setelah disalin, file di /home/source akan dilengkapi dengan file dari /source.

Ini adalah masalah logis: kita dapat menambahkan file ke direktori tujuan jika nama foldernya sama, tetapi jika berbeda, maka folder sumber akan ditempatkan di dalam tujuan. Bagaimana cara menyalin file dari/sumber ke/target menggunakan cp tanpa wildcard?

Untuk mengatasi batasan berbahaya ini, kami menggunakan solusi yang tidak jelas:

cp -a /source/. /target

Mereka yang akrab dengan DOS dan Linux sudah memahami segalanya: di dalam setiap folder ada 2 folder tak kasat mata β€œ.” dan β€œ..”, yang merupakan tautan folder semu ke direktori saat ini dan yang lebih tinggi.

  • Saat menyalin cp memeriksa keberadaan dan mencoba membuat /target/.
  • Direktori seperti itu ada dan itu adalah /target
  • File dari/source disalin ke/target dengan benar.

Jadi, gantungkan dalam bingkai tebal di memori Anda atau di dinding:

cp -a /source/. /target

Perilaku perintah ini jelas. Semuanya akan berfungsi tanpa kesalahan, terlepas dari apakah Anda memiliki sejuta file atau tidak sama sekali.

Temuan

Jika Anda perlu menyalin semua file dari satu folder ke folder lain, kami tidak menggunakan wildcard, lebih baik menggunakannya saja cp dikombinasikan dengan titik di akhir folder sumber. Ini akan menyalin semua file, termasuk yang tersembunyi, dan tidak akan gagal dengan jutaan file atau tidak ada file sama sekali.

penutup

vmspike menyarankan versi perintah dengan hasil serupa:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

CATATAN: kotak surat T memiliki arti. Jika Anda mencampurnya, Anda akan mendapatkan sampah total: arah penyalinan akan berubah.
агодарности:

  • Perusahaan RUVDS.COM untuk dukungan dan kesempatan untuk mempublikasikan di blog Anda di HabrΓ©.
  • Per gambar Konsep Tiga Kali Lipat. Gambarnya sangat besar dan detail, dapat dibuka di jendela terpisah.

PS Silakan kirimkan kesalahan apa pun yang Anda lihat melalui pesan pribadi. Saya meningkatkan karma saya untuk ini.

perintah cp: salin folder file dengan benar ke * nix

Sumber: www.habr.com

Tambah komentar