Neden bir alıntı tilde ('~') cd alamıyorum?


32

İlk senaryomu yazdığım için bunun temel bir soru olduğundan eminim, ancak biri bana neden yapabileceğimi açıklayabilir:

cd ~
cd bin
cd ~/bin
cd 'bin'

Ama değil

cd '~'
cd '~/bin'

Ben gerek cdben tırnak (Windows var lüzum böylece dizin isimlerinden birinde bir boşluk içeren bir dizin yolu Program Filesşarap altında). İki cdkomutla bunun üstesinden gelebilirim, ama neden ~alıntı yapamıyorum ?

Eğer yazarsam cd '~'(veya cd "~") alırım:

bash: cd: ~: No such file or directory

29
Eğer Kendinize şunu sorun: etmedi bu şekilde çalışmaz, nasıl olur cdbir dizine adında ~?
Jörg W Mittag

2
Bir yazar olarak, bir komut dosyası yazıyorsanız mutlak yolları kullanmalı ve tamamen kaçınmalısınız cd. Birden çok kez yazmak istemediğiniz yol adlarını saklamak için değişkenleri kullanın, örn.pf=~/.wine/drive_c/Program\ Files/; cp /path/to/file "$pf"
tatlı

8
@jamesqf: Neden mantıklı bir sistem dosyalarımı ve dizinleri adlandırmak istediğimi benden daha iyi bildiğini varsayıyor? Ayrıca, Unix'in neden yol bileşen ayırıcılarının ve yol sonlandırıcılarının bant içi sihirli sinyalleriyle gittiğini hiç anlamadım. /Veya adlı bir dosya / dizinde yanlış olan ne NUL?
Jörg W Mittag

3
@ JörgWMittag muhtemelencd ./~
k_g

2
@jamesqf Tarihsel olarak Unix dosya sistemlerinin, Jorg'ın belirttiği gibi, '/' (yol ayırıcı) ve '\ 0' (NUL - string-termination char) dışındaki bir dosya adında herhangi bir karaktere izin verdiğini belirtmek isteriz. Başka kısıtlama yok. Pek çok Unix dosya sistemi uygulaması olmuştur, bu yüzden bunlardan herhangi birine kısıtlamalar getirilmesi uyumsuzluğu ve karmaşıklığı arttırmıştır - ve “garip” olarak görülmüştür! Ve '~' genişlemesi sadece son zamanlarda csh içinde ve daha çok bash'te nispeten yaygın bir şekilde sunuldu, '~' karakterleri olan dosyalar / dizinler bilinmiyor (örn. Dosyamın yedeği olarak myfile).
SusanW

Yanıtlar:


78

@Karel'in cevabında belirttiği gibi, ~özel bir karakter ve Bash tarafından mevcut kullanıcının ana dizinine genişletildi. Bash'in "Tilde Expansion" kılavuzuna bakın veya manüel sayfada ( man bash) "Tilde Expansion" başlığını arayın .

Etrafındaki herhangi bir teklif, ~bu kirlenmenin genişlemesini önler.


Hala cdkendi adında boşluklar bulunan bir dizine nasıl kullanabileceğinizi sorunuzu cevaplamak için birkaç alternatif var:

  • Tırnakları atlayın ve bunun yerine ters eğik çizgi ile boşluklardan kurtulun:

    cd ~/foo/spaces\ are\ cool/bar
  • Yolun geri kalanını alıntılayın, ancak çizgiyi ve ilk eğik çizgiyi atlayın:

    cd ~/"foo/spaces are cool/bar"

    Gördüğünüz gibi, Bash içindeki kote edilmiş ve tırnak içine alınmamış dizgileri, aralarında boşluk bırakmadan yan yana yazarak birleştirebilirsiniz.

  • $HOME"Çift tırnak işareti" nde hala genişleyen tilde yerine ortam değişkenini kullanın (ancak 'tek tırnak işareti' değil):

    cd "$HOME/foo/spaces are cool/bar"

3
@ rexkogitans ~'/...'çalışmayacak ve bu cevabın sahip değil. ~/'...'ya ~/"..."çalışacak.
hvd

tld; dr: çünkü bu kabuk sözdizimi
Sergiy Kolodyazhnyy

@hvd teşekkürler. Sabit yazım hatası. Bu en eksiksiz cevaptır ve OP'nin ne yapmak istediğini nasıl çözeceğini de açıklar. ~/'path'gitmenin yolu bu.
rexkogitans

1
@hvd sadece biraz merak, neden ~'/...'işe yaramazsa? Eğik çizgi özel bir karakter değildir, bu nedenle tırnakların içinde veya dışında çalışması gerekir.
Kodos Johnson

6
@KodosJohnson Bash manpage'in "Tilde Expansion" hakkındaki bölümüne göz atın. Bunun ilgili paragrafı da aşağıdaki tatlı cevabında alıntılanmıştır. TL; DR: Tilde genişlemesi, bir kelimedeki ilk karakter bir tırnaksız tilde ise, o zaman o tilde ve bir sonraki tırnaksız eğik çizginin arasındaki her şey "tilde öneki" olarak kabul edilir. Bu önek +, -, sayı veya kullanıcı adı gibi geçerli bir şey değilse (oradaki alıntılara da izin verilmez), genişletme başarısız olur ve değişmez bir karakter elde edersiniz.
Byte Commander

17

~, kabuk tarafından oturum açmış kullanıcının ana dizini olarak yorumlanan özel bir karakterdir. '~', kabuk tarafından bir hazır bilgi ~ karakteri olarak yorumlanır, oturum açmış kullanıcının ana diziniyle değil, iki tekli alıntı karakterinin içine bir dize yerleştirmek, o dizenin değişmez metin dizisi olarak yorumlanmasına neden olur.


~anlamında bir takma ad değildir, takma addırbash : Takma adlar basit bir komutun ilk sözcüğü olarak kullanıldığında bir dizenin bir sözcüğün yerine kullanılmasına izin verir. . Aşağıdaki cevabımda açıkladığım gibi, bu bir genişleme.
tatlı

15

Bu, Tilde Expansionbash adlı bir özellik . Alıntı Yapan :man bash

Bir kelime işaretsiz tilde karakteriyle (`~ ') başlarsa, ilk tırnak işareti olmayan eğik çizgiden önceki tüm karakterler (veya tırnak işareti olmayan eğik çizgi yoksa tüm karakterler) tilde öneki olarak kabul edilir. Tilde öneki karakterlerden hiçbiri alıntılanmazsa, tilde takip eden tilde öneki karakterler olası bir giriş adı olarak değerlendirilir. Bu oturum açma adı boş dizge ise, tilde kabuk parametresi HOME değeri ile değiştirilir. HOME ayarlanmamışsa, kabuğu çalıştıran kullanıcının home dizini onun yerine kullanılır.

Genişlemenin çalışması için tilde karakterinin alıntılanması ~gerekir, aksi halde karakter tam anlamıyla alınır ve geçerli dizinde cdadında bir dizin yoksa, başarısız olur ~. Alıntı yapmanın açıklaması için bu kapsamlı cevaba bakınız bash. Yolun bir kısmını alıntı yapmanız gerekiyorsa, şunları yapabilirsiniz:

  1. en azından tek tırnak işaretleri ile alıntı yapılması gereken karakterleri, örneğin

    ~/dir' 'with' 'spaces/

    veya

    ~/'dir with spaces/'
  2. En azından çift tırnak işareti ile alıntı yapılması gereken karakterleri, örneğin;

    ~/dir" "with" "spaces/

    veya

    ~/"dir with spaces/"
  3. sadece ters eğik çizgi ile alıntı yapılması gereken karakterleri belirtir, örneğin

    ~/dir\ with\ spaces/

Tilde Expansion'ın daha ilginç özellikleri var, örneğin:

  • ~+ değerine genişler PWDmevcut çalışma dizininin
  • ~- değerine genişler OLDPWDönceki çalışma dizininin
  • ~john “john” giriş adıyla ilişkilendirilmiş olan ana dizine açılır.

Bu arada, ters eğik çizgi ile de 'overquote' tamam; ör $ touch a; cd \a. (Bunun sorun yaşayabileceğini düşündüm cd \n, ama en azından benim bash
sürümümdeki deneyler

1

Kullanarak keşfetmek echoKomutu keşfet

Bashta işlerin nasıl yürüdüğünü keşfetmenin en kolay yolu echokomuttur. Bu ~kullanım durumunda :

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo `~`
bash: /home/rick: Is a directory

Gördüğünüz gibi, tek bir alıntı yaptığınızda veya çevresinde çift tırnak işareti kullandığınızda ~, kelimenin tam anlamıyla bir dize olarak yorumlanır ve değişken olarak genişletilmez. Backticks (`) kullandığınızda komut olarak çalıştırılır ve bir hata mesajı oluşturur.

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.