cp komutu: *nix'teki dosya klasörlerini doğru şekilde kopyalamak

cp komutu: *nix'teki dosya klasörlerini doğru şekilde kopyalamak

Bu makale, kullanımıyla ilgili bazı açık olmayan şeyleri ortaya çıkaracaktır. joker kopyalarken belirsiz komut davranışı cp kopyalama sırasında ve ayrıca çok sayıda dosyayı atlamadan veya çökmeden doğru şekilde kopyalamanıza olanak tanıyan yöntemler.

Diyelim ki /source klasöründeki her şeyi /target klasörüne kopyalamamız gerekiyor.

Akla gelen ilk şey şudur:

cp /source/* /target

Bu komutu hemen şu şekilde düzeltelim:

cp -a /source/* /target

Anahtar -a tüm niteliklerin, hakların kopyalanmasını ve özyinelemeyi ekleyecektir. Hakların tam olarak çoğaltılmasının gerekmediği durumlarda bir anahtar yeterlidir -r.

Kopyaladıktan sonra tüm dosyaların kopyalanmadığını göreceğiz; noktayla başlayan dosyalar şöyle:

.profile
.local
.mc

ve benzerleri.

Bu neden oldu?

Çünkü joker karakterler kabuk tarafından işlenir (bash tipik bir durumda). Varsayılan olarak bash, noktalarla başlayan tüm dosyaları gizli olarak değerlendirdiğinden yok sayar. Bu davranışı önlemek için davranışı değiştirmemiz gerekecek bash komutu kullanarak:

shopt -s dotglob

Bu davranış değişikliğinin yeniden başlatma sonrasında da devam etmesini sağlamak için klasörde bu komutla bir joker.sh dosyası oluşturabilirsiniz. /etc/profile.d (Belki de dağıtımınızda farklı bir klasör vardır).

Kaynak dizinde dosya yoksa, kabuk yıldız işaretinin yerine hiçbir şey koyamayacak ve kopyalama da bir hatayla başarısız olacaktır. Bu duruma karşı seçenekler var failglob и nullglob. ayarlamamız gerekecek failglobBu, komutun yürütülmesini engelleyecektir. nullglob eşleşme bulamayan joker karakterler içeren bir dizeyi boş bir dizeye (sıfır uzunluk) dönüştürdüğü için çalışmaz. cp hataya neden olacaktır.

Ancak klasörde binlerce veya daha fazla dosya varsa joker karakterler yaklaşımı tamamen terk edilmelidir. Gerçek şu ki bash joker karakterleri aşağıdaki gibi çok uzun bir komut satırına genişletir:

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

Komut satırının uzunluğunun bir sınırı vardır ve bunu şu komutu kullanarak öğrenebiliriz:

getconf ARG_MAX

Komut satırının maksimum uzunluğunu bayt cinsinden alalım:

2097152

Или:

xargs --show-limits

Şöyle bir şey elde ederiz:

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

O halde joker karakterleri tamamen ortadan kaldıralım.

Hadi sadece yazalım

cp -a /source /target

Ve burada davranışın belirsizliğiyle karşı karşıyayız cp. /target klasörü yoksa ihtiyacımız olanı alacağız.

Ancak hedef klasör mevcutsa dosyalar /target/source klasörüne kopyalanacaktır.

/target klasörünü her zaman önceden silemeyiz çünkü ihtiyacımız olan dosyaları içerebilir ve örneğin hedefimiz, /target içindeki dosyaları /source'daki dosyalarla tamamlamaktır.

Kaynak ve hedef klasörler aynı şekilde adlandırılmışsa, örneğin, /source'dan /home/source'a kopyalıyorsak, o zaman şu komutu kullanabiliriz:

cp -a /source /home

Ve kopyalamadan sonra, /home/source içindeki dosyalar /source'daki dosyalarla desteklenecektir.

Bu mantıksal bir sorundur: Klasörler aynı şekilde adlandırılmışsa hedef dizine dosya ekleyebiliriz, ancak farklılarsa kaynak klasör hedefin içine yerleştirilecektir. Joker karakterler olmadan cp kullanarak dosyalar /source'dan /target'e nasıl kopyalanır?

Bu zararlı sınırlamayı aşmak için açık olmayan bir çözüm kullanıyoruz:

cp -a /source/. /target

DOS ve Linux'a aşina olanlar zaten her şeyi anlamışlardır: her klasörün içinde 2 görünmez klasör vardır "." ve mevcut ve daha yüksek dizinlere sözde klasör bağlantıları olan “..”.

  • Kopyalarken cp varlığını kontrol eder ve /target/ oluşturmaya çalışır.
  • Böyle bir dizin var ve /target
  • /source'daki dosyalar /target'e doğru şekilde kopyalandı.

O halde onu kalın bir çerçeveyle hafızanıza veya duvarınıza asın:

cp -a /source/. /target

Bu komutun davranışı açıktır. Milyonlarca dosyanız olsa da olmasa da, her şey hatasız çalışacaktır.

Bulgular

Kopyalamanız gerekiyorsa tüm dosyaları bir klasörden diğerine taşımak için joker karakterler kullanmıyoruz, bunun yerine bunları kullanmak daha iyidir cp kaynak klasörün sonunda bir nokta ile birleştirilir. Bu, gizli olanlar da dahil olmak üzere tüm dosyaları kopyalayacak ve milyonlarca dosya veya hiç dosya olmaması durumunda başarısız olmayacaktır.

Послесловие

vmspike benzer sonuca sahip bir komut sürümü önerdi:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

NOT: mektup durumu T anlamı vardır. Eğer karıştırırsanız, tamamen saçmalık elde edersiniz: kopyalama yönü değişir.
Teşekkür:

  • şirket RUVDS.COM Destek ve Habré'deki blogunuzda yayınlama fırsatı için.
  • Resim başına Üçlü Konsept. Resim çok büyük ve detaylıdır, ayrı bir pencerede açılabilir.

PS Lütfen fark ettiğiniz hataları özel mesajla gönderin. Bunun için karmamı artırıyorum.

cp komutu: *nix'teki dosya klasörlerini doğru şekilde kopyalamak

Kaynak: habr.com

Yorum ekle