Tilde (~) neden çift tırnak işaretleri içinde genişlemiyor?


54

Göre bu cevap ve kendi anlayış, yaklaşık işareti ana dizine genişler:

$ echo ~
/home/braiam

Şimdi, kabuk genişlemesinin çalışmasını istediğimde, örneğin değişken isimlerini kullanarak $FOOve beklenmedik karakterleri, bu gibi boşlukları vb. Bozmadığımı istediğimde biri çift tırnak işareti kullanmalıdır ":

$ FOO="some string with spaces"
$ BAR="echo $FOO"
$ echo $BAR
echo some string with spaces

Bu genişleme neden tilde çalışmıyor?

$ echo ~/some/path
/home/braiam/some/path
$ echo "~/some/path"
~/some/path


3
Ayrıca, komut satırında bir program argümanı sağlarken, komut argümanında --path ~/myfilegenişleyen ancak açılmayan bir tutarsızlık olduğunu unutmayın --path=~/myfile.
Ángel,



Yanıtlar:


45

Sebebi, çünkü çift tırnak içinde, tilde ~özel bir anlamı yoktur, değişmez olarak kabul edilir.

POSIX, Çift Tırnakları şöyle tanımlar :

Karakterleri çift tırnak işareti içine almak (""), dolar işareti, ters tırnak işareti ve ters eğik çizgi karakterleri hariç, çift tırnak içindeki tüm karakterlerin gerçek değerini korur,

...

Başvuru, bir çift teklifin, çift tırnak içine alınacak ters eğik çizgiden önce gelmesini sağlayacaktır. '@' Parametresinin çift tırnak işaretleri içinde özel bir anlamı vardır.

Dışında $, `, \ve @diğerleri karakterleri çift tırnak içine kadar değişmez kabul edilir.


9
Bu durumda sanırım kullanmalısın $HOME.
Seth

11
Ya da ~, örneğin, sadece teklif edemezls -l ~/"My Documents"
Andrew Medico

Bu çok sezgisel değil. Bunu yapmayı seçmelerinin sebebi nedir? (Bu cevap aslında sebebi vermez, fakat daha çok standarda işaret eder, ancak standart bir sebeple bu şekilde yazılmıştır .)
iconoclast

1
@iconoclast gerçekten "neden bu şekilde uygulandılar" istiyorsanız, bunun yerine Stephane cevabını okuyun .
Braiam

2
Yani, @iconoclast neden olan gök mavisi? :) :) :)
Jesse Chisholm

32

Tilde genişlemesi POSIX tarafından şu şekilde tanımlanır:

Bir "tilde-öneki", kelimenin başında yer alan, tırnaksız bir <tilde> karakterinden oluşur; bunu, kelimenin ilk tırnak işareti olmayan <slash> 'dan önceki tüm karakterleri veya < > çizgi. Bir ödevde, çoklu tilde önekleri kullanılabilir: [...] ödevin <equals-sign> ını takiben, herhangi bir alıntı yapılmamış <colon> veya her ikisini takip ederek. [...] Eğer tilde öneki karakterlerden hiçbiri alıntılanmamışsa, <tilde> 'dan sonraki tilde öneki karakterlere kullanıcı veri tabanından giriş yapılabilir. [...] Oturum açma adı boşsa (yani, tilde öneki sadece tilde içeriyorsa), tilde öneki HOME değişkeninin değeri ile değiştirilir. HOME ayarlanmamışsa sonuçlar belirtilmez. [...]

Bu yüzden en kısa cevap "bu şekilde tanımlandığı için" dır: önek içerisindeki karakterlerden herhangi birinin alıntılanması ~, genişlemeyi bastırır.

Ayrıca genişlemeyi her zaman tek bir kelimeyle sonuçlandığı gibi tanımlar, bu yüzden alıntı yapmak gereksiz olacaktır:

Tilde genişlemeden kaynaklanan yol adı, alan bölünmesi ve yol adı genişlemesi ile değiştirilmesini önlemek için alıntılanmış gibi işlem görmelidir.

Yolun bir kısmının alıntı yapması gerektiği, ancak gerisinin bir tilde öneki olduğu durumlarda, tilde genişlemesini ve sıradan alıntıları doğrudan birleştirebilirsiniz:

$ cat ~/"file name with spaces"

Daha geniş "neden" üzerine: kelime bölmek için makul bir kullanım olmadığından ~, alıntı yapılmasını istemek yerine varsayılan davranış bu olmalıdır. Çünkü alıntı yapmaya gerek yok, ~tırnak işaretleri içinde özel bir anlam vermek gereksiz bir komplikasyon olabilir. Ve elbette, tarihsel nedenler, arzu edilse bile, şimdi değiştirilemeyeceği anlamına gelir.


Göre bu bash kılavuzunda , yaklaşık yorumlaması olur önce boşluk ayırma. Ana dizinde boşluk olsa bile, tilde genişlemesini güvenli bir şekilde yapmanın bir yolu var mı? Normalde, elbette, böyle bir şey yaparsınız "".
Lucretiel

Genişleme tek bir kelimedir; cevabın ikinci alıntı geçidine bakınız.
Michael Homer

23

~ Korn kabuğuna eklenmeden ve daha sonra POSIX kabuğuna spesifikasyona eklenmeden çok önce C kabuğunda ortaya çıkar.

C-kabuğunda ~bir küreselleştirme işleci ( *.txtörneğin genişleyen ile aynı rutin tarafından genişletilmiş ), bu yüzden küreselleşmenin geri kalanı çift tırnak içinde yapılmamıştır.


11

Bu neden bu şekilde tasarlandığına cevap vermese de, $HOMEyerine kullanmanız gerekiyorsa bunun yerine kullanırsınız , çünkü esasen budur ~.

$ echo "$HOME/some/path"
/home/braiam/some/path

6
bu işe yaramazsa~otheruser
Johannes Kuhn

2
Doğru, ama bunu yapabilirsiniz: ONLARI = ~ otheruser sonra kullanmak "BUNLARI, $ / bir / yol"
melds

1
Geçici çözüm, değişkenlerden ve çift tırnak içinde genişletilmiş diğer şeylerden farklı ~otheruserşekilde davranmanın ne kadar kötü bir fikir olduğunu gösterir ~.
iconoclast
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.