Linux ardışık çoklu yol ayırıcıları (/ home //// kullaniciadi /// dosya) nasıl işler?


111

Dosya konumlarını bir scp alt işlemine geçiren bir python betiği üzerinde çalışıyorum. Her şey yolunda, ama yolun üzerinde 'ikiye katlayacak şekilde bir dosya adı ile bir yolu birleştirme ile sonuçlanabileceğim bir durumdayım /. Birden fazla dosya ayırıcınız varsa bash'in umrunda olmadığını biliyorum, ama bunun tam olarak nasıl düzeltildiğini merak ediyorum. Fazladan soyunan bash mı, /yoksa hiç önemi yok mu?

Sordum çünkü /birleştirme sırasında fazladan s kontrolü yapmak için bana birkaç kod satırı kazandıracak . Önemli değil, ama merak ediyorum da. Bir satırda birden çok s kullanmanın bir önemi olabileceği anlaşılan satırın cd //usr(yerine cd /usr) olan bir bash betiği var./


7
Ekstra kod satırlarına yatırım yapardım ...
Stefan

5
Her ihtimale karşı herkes ben aslında python kullanarak sonuna MUYDUNUZ, ben kimse tanımıyor eminim ki, umurunda joinve abspathve bu tür komutları.
Falmarri

Yanıtlar:


165

Birden çok eğik çizgiye izin verilir ve tek bir eğik çizgiye eşdeğerdir. Kaynaktan Tek Unix tarifnamede (versiyon 3) , temel tanımları §3.266 yol adı , “Her ardışık eğik bir çizgi ile aynı olarak kabul edilir”

Bunun bir istisnası var: bir yol adı tam olarak iki eğik çizgiyle başlarsa, farklı şekilde ele alınabilir (ref: temel tanımlar §4.11 yol adı çözünürlüğü ). Bazı uygulamalar yapabileceği gibi Linux kendisi de bunu yapmaz, diğer unix-ish sistemleri de yapar (örneğin Cygwin).

Bir /yol adının sonundaki iz , yol adını bir dizine yönlendirmeye zorlar. (İn POSIX 1003.1-2001 (Tek UNIX v3) taban tanımlar §4.11 yol adı çözünürlüğü , bir arka /bir eğik eşdeğerdir /.. POSIX §4.12 1.003,1-2.008 (Tek UNIX v4) temel tanımlamaları gereksinimi ortadan kaldırır için eşdeğer şekilde /.üzere, var olmayan dizinlerle başa çıkmak için (örneğin mkdir foo/çalışması gerekir, oysa mkdir foo/.olmaz - değişim için gerekçeyi görün ).

Bir dizin girişi üzerinde çalışan programlar için, bir dizine foosembolik bir link ise, geçiş foo/yapmak, programın sembolik link yerine dizinde hareket etmesini sağlamanın bir yoludur.

This Bunun yalnızca yol adı çözünürlüğü için geçerli olduğunu, yani dosyalara erişirken geçerli olduğunu unutmayın. Dosya adı manipülasyonları farklı çalışabilir. Örneğin basenameve dirnamesondaki eğik çizgileri yok sayın.


7
Eşdeğer /.bir sonraki tartışma sürecinden sonra belirsiz olduğu için kaldırılmıştır. Her neyse, bu bilgiyi iyi bir şekilde özetlemek için +1 zor.
hakre

17

İşletim sistemi de bunu önemsemiyor, yolunda bir // ile açmak için doğrudan bir çağrı ile bir C programını denedim.

Bunu normalleştirmek için python kütüphane işlevini kullanabilirsiniz. Diğer diller benzer işlevlere sahiptir.

http://docs.python.org/library/os.path.html#os.path.normpath


5
Normpath kaynağında aşağıdaki yorumu dikkate alın: Bir yolu normalleştirin, örn. A // B, A /./ B ve A / foo /../ B hepsi A / B olur. Sembolik bağlantılar içeriyorsa, bunun yolun anlamını değiştirebileceği anlaşılmalıdır!
Bluehorn

8

Gördüğüm tüm Unix sistemlerinde tek aynıdır /, ama Unix standardı belirtir

İki ardışık eğik çizgiyle başlayan bir yol adı, uygulama tarafından tanımlanmış bir şekilde yorumlanabilir, ancak ikiden fazla eğik çizgi tek bir eğik çizgi olarak değerlendirilir.

bu nedenle sisteminize bağlı olarak özel olarak kullanılabilir. (Bazı eski Unix sürümleri /, uzak dosya sistemine erişim için çift ​​yönlendirici kullandı ve hala bazıları olabilir.)


7
Cygwin (gerçek bir UNIX olmasa da) //remote/..., muhtemelen Windows'la tutarlılık sağlamak için uzak dosya sistemine erişim anlamına geliyor \\remote\....
efemient

2
Windows POSIX uyumlu API'lerin de //remote/...UNC yol \\remote\...formatıyla aynı şekilde davranacağına inanıyorum (ancak şu anda iyi bir referans alamıyorum) .
Stephen P

1
Boost.Filesystem'in taşınabilir yol adlarının , Unix / POSIX teknik özelliklerine uygun olarak mutlak //olduklarını test edebileceklerini özel bir şekilde ele aldıklarını hatırlıyorum false.

7

os.path.joinPython'da kullanın , birden fazla eğik çizgi almazsınız. Dizeleri birleştirerek dosya adlarını kendiniz oluşturmak, Python stilinin zayıf olduğu düşünülür.


Katılıyorum, ancak dosya adı bir komut dizesinin parçası ve dosya adını eklemek için komut dizisini ayrıştırmak yerine (sonunda) eklemek istiyorum.
Falmarri

1
@Falmarri: Bir komut ismine sadece bir dosya ismi ekleyemezsiniz! Bir komut dizesi kabuk tarafından ayrıştırılır, bu nedenle dosya adlarındaki özel karakterlerin alıntılanması gerekir. Bu nedenle, dosya adını oluşturmanız ve komut dizisine koymak için doğru şekilde alıntı yapmanız gerekir.
Gilles

Bu gerçekten kendimi kullanacağım gerçekten özel bir proje. Muhtemelen bu konuda güçlü olmamak için yeterince açık olmamıştım. Bu dosya yolu dizesini, bana doğru şekilde çıkarılan bir dosya yolunu veren bir sınıftan alıyorum. Ve ben bir komut satırı argümanı e ekleyerek ediyorum
Falmarri

1
@Falmarri: Yani kontrol etmediğiniz komut satırı değerini temizlemek için normpath kullanın ve sonra bunları birleştirmek için join kullanın.
Neil Mayhew

Bu aslında benim yaptığım şeydir /.
Falmarri

3

Arada fark yok.

Birden fazla eğik çizgi göz ardı edilir (etkisiz), örneğin:

ls -al //usr///////bin/sed

7
Orada olabilir tam olarak iki eder ve başında olabilirlerdi; Ardışık iki eğik çizgiyle başlayan bir yol adı, uygulama tarafından tanımlanmış bir şekilde yorumlanabilir . Uygulamada bunun doğru olduğunu düşünüyorum ve göz ardı ediliyorlar
Michael Mrozek

Teşekkürler Chris, açıklama için teşekkür ederim! (Maalesef OpenID girişi benim için çalışmıyor ya da size oy veririm)

@Rob Kaydoldunuz, ancak hala giriş yaptınız (çereziniz tarafından takip ediliyorsunuz). Bir OpenID'yi hesabınıza bağlamak için şimdi kayıt olmalısınız, ancak her iki şekilde de oy verebilmelisiniz
Michael Mrozek

Teşekkürler Michael ama "oy vermek için giriş yapmalı veya kayıt olmalısınız". Yalnızca bir e-posta adresi ve adı kullandığınızda, tam ayrıcalıklarınız yoktur. OpenID zaman aşımına uğradığından ve başka bir hesap oluşturmak istemiyorum çünkü şansım yaver gitti. Tembel olmak benim suçum sanırım, ama yardımı takdir ediyorum.

0

Elbette bir yolu içinden geçerek olası çoklu / (eğik çizgiler) ile normalleştirebilirsiniz. tr -s

NORMALIZED=$(echo "$UNHYGIENIC" | tr -s / /)

... ve kullan $NORMALIZED

Ancak, gerekli olması gerekir. Doğru bir şekilde bildiğim kadarıyla UNIX çekirdeği eşzamanlı yol ayırıcıları görmezden gelmelidir --- ya da kavramsal olarak onlara /./...


"yapmalı" -> "yapmamalı".
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.