
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.
