arahan cp: menyalin folder fail dengan betul dalam *nix

arahan cp: menyalin folder fail dengan betul dalam *nix

Artikel ini akan mendedahkan beberapa perkara yang tidak jelas berkaitan dengan penggunaan kad bebas apabila menyalin, tingkah laku arahan yang samar-samar cp semasa menyalin, serta kaedah yang membolehkan anda menyalin sejumlah besar fail dengan betul tanpa melangkau atau terhempas.

Katakan kita perlu menyalin segala-galanya daripada folder /source ke folder /target.

Perkara pertama yang terlintas di fikiran ialah:

cp /source/* /target

Mari segera betulkan arahan ini kepada:

cp -a /source/* /target

Kunci -a akan menambah penyalinan semua atribut, hak dan menambah rekursi. Apabila pengeluaran semula hak yang tepat tidak diperlukan, kunci adalah mencukupi -r.

Selepas menyalin, kami akan mendapati bahawa tidak semua fail disalin - fail bermula dengan titik seperti:

.profile
.local
.mc

dan seumpamanya.

Mengapa ini berlaku?

Kerana kad bebas diproses oleh shell (bash dalam kes biasa). Secara lalai, bash akan mengabaikan semua fail bermula dengan titik, kerana ia menganggapnya sebagai tersembunyi. Untuk mengelakkan tingkah laku ini kita perlu mengubah tingkah laku bash menggunakan arahan:

shopt -s dotglob

Untuk memastikan perubahan tingkah laku ini berterusan selepas but semula, anda boleh mencipta fail wildcard.sh dengan arahan ini dalam folder /etc/profile.d (Mungkin pengedaran anda mempunyai folder yang berbeza).

Dan jika tiada fail dalam direktori sumber, maka shell tidak akan dapat menggantikan apa-apa sebagai ganti asterisk, dan penyalinan juga akan gagal dengan ralat. Terdapat pilihan terhadap situasi ini failglob ΠΈ nullglob. Kita perlu menetapkan failglob, yang akan menghalang arahan daripada dilaksanakan. nullglob tidak akan berfungsi, kerana ia menukar rentetan dengan kad bebas yang tidak menemui padanan menjadi rentetan kosong (panjang sifar), yang selama cp akan menyebabkan ralat.

Walau bagaimanapun, jika terdapat beribu-ribu fail atau lebih dalam folder, maka pendekatan kad bebas harus ditinggalkan sama sekali. Hakikatnya ialah bash mengembangkan kad bebas menjadi baris arahan yang sangat panjang seperti:

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

Terdapat had pada panjang baris arahan, yang boleh kita ketahui menggunakan arahan:

getconf ARG_MAX

Mari dapatkan panjang maksimum baris arahan dalam bait:

2097152

Или:

xargs --show-limits

Kami mendapat sesuatu seperti:

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

Jadi, mari kita lakukan tanpa kad bebas sama sekali.

Mari kita menulis

cp -a /source /target

Dan di sini kita berhadapan dengan kekaburan tingkah laku cp. Jika folder /target tidak wujud, maka kita akan mendapat apa yang kita perlukan.

Walau bagaimanapun, jika folder sasaran wujud, maka fail akan disalin ke folder /target/sumber.

Kami tidak boleh sentiasa memadam folder /target terlebih dahulu, kerana ia mungkin mengandungi fail yang kami perlukan dan matlamat kami, sebagai contoh, adalah untuk menambah fail dalam /target dengan fail daripada /source.

Jika folder sumber dan destinasi dinamakan sama, sebagai contoh, kami menyalin dari /source ke /home/source, maka kami boleh menggunakan arahan:

cp -a /source /home

Dan selepas menyalin, fail dalam /home/source akan ditambah dengan fail daripada /source.

Ini adalah masalah logik: kita boleh menambah fail ke direktori destinasi jika folder dinamakan sama, tetapi jika ia berbeza, maka folder sumber akan diletakkan di dalam destinasi. Bagaimana untuk menyalin fail dari /sumber ke /sasaran menggunakan cp tanpa kad bebas?

Untuk mengatasi had berbahaya ini, kami menggunakan penyelesaian yang tidak jelas:

cp -a /source/. /target

Mereka yang biasa dengan DOS dan Linux telah memahami segala-galanya: di dalam setiap folder terdapat 2 folder yang tidak kelihatan "." dan "..", yang merupakan pautan pseudo-folder ke direktori semasa dan lebih tinggi.

  • Apabila menyalin cp menyemak kewujudan dan cuba mencipta /target/.
  • Direktori sedemikian wujud dan ia adalah /target
  • Fail dari /sumber disalin ke /sasaran dengan betul.

Jadi, gantungkannya dalam bingkai tebal dalam ingatan anda atau di dinding:

cp -a /source/. /target

Tingkah laku arahan ini jelas. Semuanya akan berfungsi tanpa ralat, tidak kira sama ada anda mempunyai sejuta fail atau tiada langsung.

Penemuan

Jika anda perlu menyalin semua fail dari satu folder ke folder yang lain, kami tidak menggunakan kad bebas, lebih baik menggunakannya sebaliknya cp digabungkan dengan noktah di hujung folder sumber. Ini akan menyalin semua fail, termasuk yang tersembunyi, dan tidak akan gagal dengan berjuta-juta fail atau tiada fail sama sekali.

afterword

vmspike mencadangkan versi arahan dengan hasil yang serupa:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

NOTA: kes surat T mempunyai makna. Jika anda mencampurkannya, anda akan mendapat sampah lengkap: arah penyalinan akan berubah.
terima kasih:

  • Syarikat-syarikat RUVDS.COM untuk sokongan dan peluang untuk menerbitkan di blog anda di HabrΓ©.
  • Setiap imej Konsep Bertiga. Gambarnya sangat besar dan terperinci, boleh dibuka dalam tetingkap yang berasingan.

PS Sila hantar sebarang ralat yang anda perasan dalam mesej peribadi. Saya meningkatkan karma saya untuk ini.

arahan cp: menyalin folder fail dengan betul dalam *nix

Sumber: www.habr.com

Tambah komen