cp ne zaman garip davranır. (nokta) veya .. (nokta nokta) kaynak dizindir


15

Bu cevap gizli olanlar dahil - - Bir tüm dosyaları kopyalayabilirsiniz ortaya koymaktadır dizinden srcdizine destşöyle:

mkdir dest
cp -r src/. dest

Yanıtın veya yorumunda bunun neden gerçekten işe yaradığına dair bir açıklama yok ve kimse de bununla ilgili belge bulamıyor.

Birkaç şey denedim. İlk olarak, normal durum:

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src dest
$ ls -A dest
dest_file  src

Sonra, birlikte /.sonunda:

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/. dest
$ ls -A dest
dest_file  .dotfile  src_dir  src_file

Yani, bu çok benzer şekilde davranır *, ancak gizli dosyaları da kopyalar.

$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/* dest
$ ls -A dest
dest_file  src_dir  src_file

.ve burada açıklandığı.. gibi uygun sabit bağlantılar gibi, dizin girişinin kendisi gibi .

Bu davranış nereden geliyor ve nerede belgeleniyor?


3
Kimsenin belgeleri bulamaması nedir? cpReferans nasıl açıkça açıklıyor cp -Rçalışır. .ve diğer ..tüm dizinler gibi dizinler, onlar hakkında büyülü veya gizemli bir şey yok.
AlexP

2
@AlexP Cevabı daha açık hale getirmek için düzenledim. Bütün mesele bu .ve ..diğer dizinler gibi davranmayın.
iFreilicht

Yanıtlar:


27

Davranış, için belgelenmiş algoritmanın mantıksal bir sonucudur cp -R. POSIX , adım 2f'ye bakın :

Dizin dosyalar source_file dizin kopyalanır edilecektir dest_file olarak dosyalarla burada listelenen dört adımı (1 ila 4) alarak source_files .

.ve ..dizinler, sırasıyla geçerli dizin ve üst dizindir. Her ikisi de kabuk söz konusu olduğunda özel değildir, bu nedenle ikisi de genişleme ile ilgili değildir ve dizin gizli dosyalar dahil olmak üzere kopyalanacaktır. *, diğer yandan, bir dosya listesine genişletilecek ve gizli dosyaların filtrelendiği yer burasıdır.

src/.Geçerli dizini içinde olan srcbir, srckendisi; src/src_dir/..olduğu src_diryine bireyin üst dizin, src. Bu yüzden dışarıdan src, eğer srcbir dizin ise, kaynak dosyası olarak belirtilir src/.veya eşdeğerdir ve gizli dosyalar da dahil olmak üzere içeriğini kopyalar .src/src_dir/..cpsrc

Belirtilmesi gereken nokta, bir dizin (veya bir dizine sembolik bağlantı) src/.olmasa bile başarısız srcolacağıdır src. Ayrıca kendisini srckopyalamadan yalnızca içeriğini kopyalar src; bu da belgelere uyuyor:

Eğer hedef varolan dizin var ve isimleri, dosya hiyerarşisindeki her dosya için karşılık gelen hedef yolunun ismi birleştirme olacak hedefi , tek bir eğik çizgi karakteri hedef eğik çizgi sona olmasaydı ve dosya göreli yol adı kaynak_dosyasını içeren dizine .

Yani cp -R src/. destkopya içerikleri srciçin dest/.(kaynak dosyası .içinde src), oysa cp -R src destkopya içerikleri srciçin dest/src(kaynak dosyasıdır src).

Bu düşünmek için başka bir yol kopyalama karşılaştırmaktır src/src_dirve src/.yerine karşılaştırarak src/.ve src. .tıpkı src_dirönceki davadaki gibi davranır .


Ama aynı şekilde davranmıyor. Belirtme srciçine dizin kopyalar dest, src/.içeriğini kopyalar. Soruda bunu daha açık hale getirmeye çalışacağım.
iFreilicht

Orada, altta yatan sorunuzu cevapladığını düşünüyorum.
Stephen Kitt

1
@ Stéphane OP kopyalamayı karşılaştırır src/.ve src/*(not değil src/.* ); src/*globbing onları yoksayarsa gizli dosyaları içermez ...
Stephen Kitt

1
Hmm, " source_file içeren dizin ". Tabii ki srciçeriyor src/.ama bir dizinin içerdiği dizinin dizini nasıl adlandırdığınıza bağlı olduğu anlamına geliyor. Tabii ki .bağlantıların bir şekilde varlığı, tüm dizinlerin kendilerini içerdiği anlamına gelir, ancak bu herkes için sezgisel olmayabilir. Bu davranış yerine, "dizin içeren dizin foo" tarafından belirleneceğini varsaymak cazip gelebilir foo/.., bu durumda fooveya foo/.: içeren sonuç dizininin aynı olması önemli değildir.
ilkkachu

1
Arasındaki ayrım olduğunu söylemek Hangi foove foo/.biraz narin görünüyor, ama ben umursamıyorum, ben de biraz eğlendiriyor bulabilirsiniz.
ilkkachu

1

Koştuğunda cp -R src/foo dest, alacaksın dest/foo. Dizin Yani eğer dest/fooyoksa, cponu oluşturacaktır ve sonra içeriğini kopyalamak src/fooiçin dest/foo.

Eğer çalıştırdığınızda cp -R src/. dest, cpgörür dest/.var ve o zaman içeriğini kopyalayarak sadece meselesi src/.için dest/..

Eğer adlı bir dizin kopyalama gibi düşün zaman .gelen srcve mevcut dizinde ile içeriğini birleştirerek dest/., bu mantıklı olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.