Perintah Cp: menyalin folder file ke * nix dengan benar



Dalam artikel ini, beberapa hal yang tidak jelas terkait dengan penggunaan wildcard saat menyalin, perilaku ambigu perintah cp saat menyalin, serta cara-cara untuk menyalin dengan benar sejumlah besar file tanpa kelalaian dan kerusakan akan diungkapkan.

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

Hal pertama yang terlintas dalam pikiran adalah:

 cp /source/* /target 

Segera perbaiki perintah ini untuk:

 cp -a /source/* /target 

Switch -a akan menambahkan salinan semua atribut, hak, dan menambahkan rekursi. Ketika reproduksi hak yang tepat tidak diperlukan, saklar -r sudah cukup.

Setelah menyalin, kami menemukan bahwa tidak semua file disalin - file yang dimulai dari titik seperti diabaikan:

.profile
.local
.mc

dan sejenisnya.

Mengapa ini terjadi?

Karena wildcard memproses shell ( bash pada kasus tipikal). Secara default, bash akan mengabaikan semua file yang dimulai dengan titik, karena memperlakukannya sebagai tersembunyi. Untuk menghindari perilaku ini, kita harus mengubah perilaku bash menggunakan perintah:

 shopt -s dotglob 

Untuk menjaga perubahan perilaku ini setelah reboot, Anda dapat membuat file wildcard.sh dengan perintah ini di folder /etc/profile.d (distribusi Anda mungkin memiliki folder yang berbeda).

Dan jika tidak ada file di direktori sumber, maka shell tidak akan dapat menggantikan apa pun untuk asterisk, dan penyalinan juga akan gagal. Terhadap situasi ini, ada nullglob dan nullglob . Kita perlu mengatur failglob , yang akan mencegah perintah mengeksekusi. nullglob tidak akan berfungsi, karena mengubah string dengan wildcard yang belum menemukan kecocokan menjadi string kosong (dengan panjang nol), yang akan menyebabkan kesalahan untuk cp .

Namun, jika ada ribuan file dan lebih banyak di folder, maka pendekatan menggunakan wildcard harus ditinggalkan sama sekali. Masalahnya, bash memperluas wildcard menjadi baris perintah yang sangat panjang seperti:

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

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

 getconf ARG_MAX 

Dapatkan panjang maksimum baris perintah dalam byte:

 2097152 

Atau:

 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

 cp -a /source /target 

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

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

Tidak selalu dapat kita menghapus folder / target di muka, karena mungkin berisi file yang kita butuhkan dan tujuan kita, misalnya, adalah untuk menambahkan file ke / target dengan file dari / sumber.

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

 cp -a /source /home 

Dan setelah menyalin file di / home / source akan menjadi file yang dilengkapi dari / source.

Itulah tugas logisnya: kita dapat menambahkan file ke direktori tujuan, jika folder diberi nama yang sama, tetapi jika berbeda, maka folder sumber akan ditempatkan di dalam penerima. 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 terbiasa dengan DOS dan Linux sudah mengerti segalanya: di dalam setiap folder ada 2 folder tak terlihat "." dan "..", yang merupakan tautan pseudo-folder ke direktori saat ini dan lebih tinggi.

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

Jadi, kita menggantung dalam bingkai tebal di ingatan kita atau di dinding:

 cp -a /source/. /target 

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

Kesimpulan


Jika Anda ingin menyalin semua file dari satu folder ke folder lain, kami tidak menggunakan wildcard, alih-alih lebih baik menggunakan cp dalam kombinasi dengan titik di akhir folder sumber. Ini akan menyalin semua file, termasuk yang tersembunyi, dan tidak akan gagal dengan jutaan file atau tidak adanya file sama sekali.

Kata penutup


vmspike menyarankan varian serupa dari perintah:

 cp -a -T /source /target 

Oz_Alex
 cp -aT /source /target 

PERHATIAN: kasus huruf T penting. Jika Anda mencampurnya, Anda mendapatkan sampah lengkap: arah penyalinan akan berubah.

Ucapan Terima Kasih:

  • Perusahaan RUVDS.COM atas dukungannya dan kesempatan untuk mempublikasikannya di blognya di Habré.
  • Per Gambar TripletKonsep . Gambarnya sangat besar dan detail, Anda bisa membukanya di jendela terpisah.

Kesalahan PS Direct yang Anda perhatikan di PM. Saya meningkatkan karma untuk ini.



Source: https://habr.com/ru/post/id471092/


All Articles