Bir dosya adında boşluğa izin verilmiyor mu?


31

Genel olarak Unix ve Linux'ta, bir dosyanın dosya adında (sıradan dosya, dir, link, aygıt dosyası, ...) boşluk bırakmaktan kaçınmanız gerektiği söylenir.

Ama bunu her zaman yapıyorum. İçinde boşluk olan bir dosya adı için,

  • Nautilus'ta boşluk karakteri boşluk olarak gösterilir.
  • Bash terminalinde, \ bir boşluğu temsil etmek için kullanıyorum ya da dosya adını bir çift çift tırnak içine aldım .
  • Bazı uygulamaların dosyalarında (Nautilus, işletim sisteminin de yapıp yapmayacağından emin değilsiniz), dosya adı, yerine boşluk bırakılarak yazılmıştır %20.

Bir dosya adında bir boşluğa gerçekten izin verilmiyor mu?

Dosya adındaki bir boşluğu nasıl kullanırsınız?


17
İzin var ama gerçekten, gerçekten sinir bozucu. Bunun için bir sebep yok. Yapma
Monica ile

3
Ayrıca -rf ~(use touch -- "-rf ~") adlı bir dosya da oluşturabilirsiniz , ancak bunu tavsiye etmem.
Ian D. Scott,

5
Bunu yapabilirsiniz, izin verilir, "cd" adlı bir kendi kendini imha eden komut dosyası oluşturmak gibi, ancak yapmamalısınız. Dosyanız zaten 3 farklı araçta farklı görünüyor, bu o kadar da kötü değil mi?
Falco,

7
Herkes bunun gerçekten, gerçekten sinir bozucu olduğu fikrini paylaşmıyor. Ve "Bunun için bir neden yok" açıkça reddetmeye ihtiyaç duymadığı için yanlıştır. Yıllar önce yerlerin nasıl düzgün bir şekilde kullanılacağını öğrendim ve öğrendim ve çoğu zaman bu gerçekten büyük bir iş değil.

2
@snailboat Uzaylar, standardizasyon eksikliği olan asıl sorunun bir belirtisidir. Unix dosya sistemleri, "ad" dosyasının neredeyse sınırsız ikili bloblara izin verir. Yalnızca geçersiz bayt 0 ve 47'dir ( /ayırıcı). Kalan 254 baytın tümü, konuşamayan eldritch "adlarının" görgü kurallarına kapıyı açar. Açıkçası bu delilik, ancak herkes "aklı başında" ne olduğu konusunda hemfikir değil ve farklı karakterler farklı araçları kıracak. Herkesin aklı ile kesişme noktası oldukça küçük .
jw013

Yanıtlar:


48

Boşluklara ve aslında /NUL hariç her karaktere dosya adlarında izin verilir. İçin öneri değil Dosya adlarında boşluk kullanmayın onlar yazılımın o kötü destekler onları tarafından yanlış anlaşılabilir diye tehlikeden geliyor. Muhtemelen, böyle bir yazılım buggy. Ancak, tartışmalı bir şekilde, kabuk komut dosyası yazma dilleri gibi programlama dilleri, içinde boşluk bulunan dosya isimleriyle sunulduğunda kırılan yazılımları yazmayı çok kolaylaştırır ve bu hataların içinde kayma eğilimi vardır, çünkü kabuk komut dosyaları, boşlukları olan dosya isimlerini kullanan geliştiriciler tarafından sıklıkla test edilmez. onlar.

İle değiştirilen boşluklar %20genellikle dosya adlarında görülmez. Bu çoğunlukla (web) URL'leri için kullanılır. URL'lerin% kodlamasının bazen dosya isimlerine girdiğini doğru olsa da, genellikle kazayla.


6
It yönettiği "URL kodlama" ya da "yüzde kodlama" en.wikipedia.org/wiki/URL_encoding en uygun adın muhtemelen "URI kodlama" olduğu gereğince, ama insanlar bulmak url daha söylemek kolay URI bu ortak bir şeklidir böylece, yanlış isim. URI'lerde ayrılmış karakter kümesinin, * nix dosya adları için olduğundan daha büyük olduğuna dikkat edin.
goldilocks

1
Bunu bilmiyorum @Tim edebilir herhangi bir komut satırı argümanı bir NULL karakteri belirtmek bash. Ctrl-V ile alıntı yapmak ve bunun gibi bir şey denemek gibi bir şey denedim $(echo -e \\0)ama işe yaramadı. Mesele şu ki, NUL'un dosya isimlerinde kullanılamamasının nedeni, C dizelerinde kullanılamaması (dizge sonlandırıcısı olduğu için) ve tüm temel API'lerin yanı sıra C programları tarafından ele alınan neredeyse tüm dizeler bu formatı kullanıyor. . Yana bashC ile yazılmıştır, sadece onları NUL ile herhangi dizeleri hiç hiçbir desteğe sahip olabilir. Yanılıyor olabilirim, belirsiz bir yol olabilir ...
Celada

1
Sıralaması içeriğe göre değişir. Dize işlevleri genellikle son boşluğu saymaz (veya daha doğrusu, ilk boş, dizenin sonudur, ondan sonra bir şeyler olsa bile), dolayısıyla bu anlamda sıfır uzunluğuna sahiptir ve bu nedenle boş sayılır.
goldilocks

3
Tabii @Celada kullanabilirsiniz NULve bash, ihtiyacınız var $'\0'. Örneğin:find . -print0 | while read -d $'\0' f; do echo "$f"; done
terdon

1
@goldilocks İnsanlar URL'yi aslında 'earl' ile kafiyeli olan 'url' olarak mı telaffuz ediyorlar?
Miles Rout,

17

Gördüğünüz gibi dosya adlarında boşluklara izin verilir.

Bu tablodaki "çoğu UNIX dosya sistemi" girişine wikipedia'da bakarsanız, şunu fark edeceksiniz:

  • Herhangi bir 8 bitlik karakter kümesine izin verilir. 8 bitlik kümelerin bir alt kümesi olduğundan ve her zaman 8 bit bayt kullanılarak gerçekleştirildiğinden, bu şemsiyenin altına 7 bitlik ASCII'yi de uygulayabiliriz.

  • Tek yasak karakterler /ve "boş". "Boş", sıfır bayt anlamına gelir, ancak bunlara yine de metin verilerinde izin verilmez.

Ancak , kabuğu herhangi bir şekilde kullanırsanız, en önemlisi *, bir POSIX globbing operatörü olan bir güçlük yaratacak bazı karakterler olduğunu fark edebilirsiniz .

Eğer "zorluk" tanımlamak istiyorum nasıl bağlı olarak, olabilir bununla alıntı ihtiyacını yaratır gibi orada boşluk (boşluk, sekme, yeni satır, vs.) içerir "". Ama bu kaçınılmazdır, çünkü boşluklara izin verilir, yani ...

Dosya adındaki bir boşluğu nasıl kullanırsınız?

Bir kabuk / komut satırı bağlamında, dosya adını tek veya çift tırnak içine alın (ancak aynı WRT ile aynı olmadıklarına dikkat edin ) veya \örneğin:

> foo my\ file\ with\ spaces\ in\ the\ name

1
NUL karakterini bash olarak nasıl belirtirsiniz? Dosya adıyla test etmek istiyorum.
Tim

1
Yapamazsın "Anlam anlamını yürüt" ifadesi, C (ve bildiğim her dilden) metin dizelerinin boş olarak sonlandırıldığı anlamına gelir. Kabuk C'ye uygulanmıştır. Aklıma gelen en sinsi şey, touch $(echo -e "foo\00bar")- sekizlik bir değer olarak -eişlenir \0N, ancak yine de bir yerde kaybolur, bu sadece adında bir dosya oluşturur foobar. Tabii ki NULL yazdırılamaz, ancak C string kısıtlaması nedeniyle oradan gittiğini garanti ediyorum.
goldilocks

"metin dizeleri boş bırakıldı " -> Daha fazla açıklama yapmak için: dizeler sonunda her zaman sıfır bayt ile saklanır, bu nedenle metinde "izin verilmez" ifadesi: Bir tane eklerseniz, dizgiyi etkin bir şekilde sonlandırdınız bu noktada. Örneğin, çoğu niyet ve amaç için foo[NULL]barolduğu gibi sonuçlanacaktır foo. Bununla gerçekleşmeyen gerçek, echo -eNULL'un bir yerde budandığını gösteriyor.
goldilocks

5
Programlama dillerinin büyük bir çoğunluğu stringlerde boş karakterlere izin verir. Bu sadece, Unix'in kurulu olduğu C olmayan ana dilin olduğu anlamına gelir - ve çoğu Unix kabukları da dizelerde boş karakterlere izin vermez. Her durumda, @Tim, tüm Unix arayüzleri boş sonlandırılmış dizgiler kullanır, bu nedenle boş bayt hiç bir dosya adında sahip olamayacağınız tek şeydir (artı /dizin ayırıcı ve alıntı yapılamaz, yani bir yol adında olabilir) ancak bir dosya adına değil).
Gilles 'SO- kötülük' dur

1
... ama [tekrar boşver]. Zaten çok sık yapacağım bir şey değil. Aklıma göre onların metinsel veri olması için hiçbir sebep yoktur. Bunu düzeltirdim, ama bu bir yorum.
goldilocks

3

Sebebi büyük ölçüde tarihseldir - Zaman isimleriyle geri dönüş, dosya isimlerinde boşluklara izin verilmedi, bu yüzden boşluklar anahtar kelime / dosya adı ayırıcıları olarak kullanıldı. Gelecekteki kabuk tercümanların eski senaryolarla ters uyumlu olması gerekiyordu ve bu nedenle bugün başımıza gelen baş ağrıları ile sıkışıp kaldık.

İnsanlarla çok fazla uğraşması gerekmeyen süreç geliştiricileri, alanları tamamen bırakarak işleri çok daha kolaylaştırabilir. Apple bunu yapar, / System / Library / CoreServices / içeriği çok az boşluk içeriyor, boşluklu programlar kullanıcı adına açılıyor ve WeuldLookStrangeIfCamelCased. Sadece benzer tek-tek yollar da boşluklardan kaçınır.

(biraz ilgili anekdot: 90'lı yılların ortalarında bir Windows uçağı "Mac'te yapabileceğim bir şeyi Windows'ta yapamayacağım bir şey söyle" -> "Dosya adında 12 karakter kullan." -> Sessiz. bu 12 karakterde de mümkün)


1
Eskiden V6 Unix kullandım (1978). Spaces edildi , sonra izin verdi. Yaptığım görevlerden biri, dosya sistemini (doğrudan disk g / ç kullanarak) ayrıştırmak için bir program yazmak ve adında boşluk ve geri alanları olan bir dosyayı aramaktı.
wallyk

boşlukları tamamen mi bırakıyorlar - ya da dosya isimleri çok az boşluk mu içeriyor?
mikeserv

2

Yani evet, başka yerlerde birçok kez belirtildiği gibi bir dosya adı hemen hemen her karakter içerebilir. Ama bu söylenmesi gerekiyor dosya adı olduğu değil dosya. Bu bir dosya gibi bazı ağırlığını taşıyacak yapar özniteliği genellikle bir dosya adı verilmesi gerektiğinden açmak bir dosya, ancak dosyanın ismi sadece işaret fiili dosyaya. Gerçek bir dosyaya daha yakın bir değer olan inode numarasının yanında onu kaydettiren dizinde depolanan bir bağlantıdır .

Yani, ne istersen onu ara. Çekirdek umrumda değil - işleyeceği tüm dosya referansları yine de gerçek inode numaralarıyla ilgilenecek. Dosya adı insan tüketimi için bir şeydir - çılgınca bir şey yapmak istiyorsanız, dosya sisteminizdir. Burada çılgınca şeyler yapacağım:

İlk önce 20 dosya yaratacağım ve onları boşluktan başka bir şey olmadan adlandıracağım.

until [ $((i=$i+1)) -gt 20 ]
do  v=$v' ' && touch ./"$v"
done

Bu çok eğlenceli. Şuna bak ls:

ls -d ./*
./      ./          ./              ./                  ./                 
./      ./          ./              ./                  ./                  
./      ./          ./              ./                  ./                   
./      ./          ./              ./                  ./     

Şimdi bu dizini yansıtacağım:

set -- * ; mkdir ../mirror
ls -i1qdU -- "$@" |
sh -c 'while read inum na
    do  ln -T "$1" ../mirror/$inum
    shift ; done' -- "$@"
ls -d ../mirror/*

İşte ../mirror/içeriği:

../mirror/423759  ../mirror/423764  ../mirror/423769  ../mirror/423774
../mirror/423760  ../mirror/423765  ../mirror/423770  ../mirror/423775
../mirror/423761  ../mirror/423766  ../mirror/423771  ../mirror/423776
../mirror/423762  ../mirror/423767  ../mirror/423772  ../mirror/423777
../mirror/423763  ../mirror/423768  ../mirror/423773  ../mirror/423778

Tamam, ama belki soruyorsun - peki bu ne? Hangisinin hangisi olduğunu nasıl söyleyebilirsiniz? Doğru inode numarasını doğru dosya adına bağladığınızdan nasıl emin olabilirsiniz?

İyi...

echo "heyhey" >>./'    ' 
tgt=$(ls -id ./'    ')
cat ../mirror/${tgt%% .*} \
    $(ls -1td ../mirror/* | head -n1) 

ÇIKTI

heyhey
heyhey

Bakınız, hem içinde bulunan ../mirror/"${tgt%% .*}"hem de referansta belirtilen inode numarası ./' 'aynı dosyaya atıfta bulunur. Aynı dosyayı tanımlarlar. İsmini veriyorlar ama başka bir şey yok. Gizem yok, gerçekten, sadece kendiniz için yapabileceğiniz bazı rahatsızlıklar, ancak sonuçta unix dosya sisteminizin çalışması üzerinde hiçbir etkisi olmayacak.

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.