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:
CATATAN: kotak surat T memiliki arti. Jika Anda mencampurnya, Anda akan mendapatkan sampah total: arah penyalinan akan berubah.
Π°Π³ΠΎΠ΄Π°ΡΠ½ΠΎΡΡΠΈ: