~ Her zaman $ HOME eşittir


40

Bunun daha önce sorulduğunu biliyorum, ancak Google’da bulamadım.

verilmiş

  • Linux çekirdeği
  • $ HOME değiştiren yapılandırma yok
  • darbe

Will ~ == $HOMEdoğru?


3
Buna inanıyorum, ancak bu Linux'a özgü bir konu değil. Aksine, herhangi bir POSIX ortamında ~buna eşdeğer olacağına inanıyorum $HOME; ama yanılıyor olabilirim.
HalosGhost

4
Aşağıdaki cevaplara rağmen… her zaman değil. Karşılaştırma echo "~"ve echo "$HOME".
Sparhawk

@Sparhawk Bekle, yani 1 + 1 2 değil mi? Bu bir komplo! Hükümet bizden bir şey saklıyor! : P
Doorknob

1
@Sparhawk, OP doğrusu ya alıntı vermedi fark edeceksiniz ~ya $HOME. : P
HalosGhost

2
@HalosGhost Ah, iyi nokta. (Ayrıca, daha sonra Michael Homer'in cevabının "tek bir alıntı ~" düştüğünü fark ettim .) Her neyse, benim gibi sıradan bir okuyucu için akılda tutulması gereken bir şey.
Sparhawk

Yanıtlar:


46

Anlaşılması gereken şey, ~genişlemenin kabuğun (bazı mermilerin) bir özelliği olması, kullanıldığı dizinde kullandığınız ana dizinden ziyade sihirli bir karakter değildir.

Genişletilir (komut satırlarını yorumlamak için kullanılan bir uygulama olan kabuk gibi), $varkomut çalıştırılmadan önce bir kabuk komut satırında kullanıldığında bazı koşullar altında değerine genişletilir.

Bu özellik ilk olarak 1970'lerin sonunda C-kabuğunda ortaya çıkmıştı (Bourne kabuğu ona sahip değildi, ya da selefi Thompson kabuğuna sahip değildi), daha sonra Korn kabuğuna (Bourne kabuğuna daha yeni bir kabuk üzerine inşa edilmiş) ilave edildi. 80s). Sonunda POSIX tarafından standardize edilmiştir ve artık POSIX dışındakiler de dahil olmak üzere çoğu kabukta mevcuttur fish.

Kabuklarda bu kadar yaygın kullanımda olduğundan, bazı kabuk dışı uygulamalar da onu ana dizinin anlamı olarak tanır. Bu onların yapılandırma dosyaları veya birçok uygulamaların durum kendi komut satırında ( mutt, slrn, vim...).

bashözellikle (GNU projesinin kabuğu olduğu ve birçok Linux tabanlı işletim sisteminde yaygın olarak kullanılan), çağrıldığı zaman sh, çoğunlukla POSIX kurallarının~ genişlemeyle ilgili kurallarına uyar ve POSIX tarafından belirtilmeyen alanlarda, çoğunlukla Korn kabuğu gibi davranır ( bu bir parça klonudur).

İken $var(iç tek tırnak hariç) çoğu yerde genişletilir, ~genişleme, sonradan sadece birkaç belirli koşullarda genişletilir ediliyor.

Liste bağlamlarında, bir dizgenin beklendiği bağlamlarda kendi argümanında genişletilir.

İşte nerede genişlediğine dair birkaç örnek bash:

  • cmd arg ~ other arg
  • var=~
  • var=x:~:x(POSIX tarafından istenen PATH, MANPATH... gibi değişkenler için kullanılır .)
  • for i in ~
  • [[ ~ = text ]]
  • [[ text = ~ ]]( ~AT&T'de bir model olarak alınmasının genişlemesi kshancak bash4.0'dan beri değil ).
  • case ~ in ~) ...
  • ${var#~} (bazı diğer kabuklarda olmasa da)
  • cmd foo=~(ancak, çağrıldığında değil sh, yalnızca sol tarafındakiler =kote edilmemiş bir bashdeğişken adı şeklinde olduğunda )
  • cmd ~/x (açıkça POSIX tarafından istenmektedir)
  • cmd ~:x(ama değil x:~:xveya x-~-x)
  • a[~]=foo; echo "${a[~]} $((a[~]))" (diğer bazı kabuklarda değil)

İşte genişlemediği birkaç örnek:

  • echo "~" '~'
  • echo ~@ ~~(Ayrıca ~u, kullanıcının ana dizinine genişletmek gerektiğini unutmayın u).
  • echo @~
  • (( HOME == ~ )), $(( var + ~ ))
  • ile extglob: case $var in @(~|other))...(olsa case $var in ~|other)Tamam).
  • ./configure --prefix=~( --prefixgeçerli bir değişken adı olmadığı için)
  • cmd "foo"=~(içinde bashtırnak işaretleri nedeniyle).
  • olarak çağrıldığında sh: export "foo"=~, env JAVA_HOME=~ cmd...

Neye genişlediğine gelince: ~tek başına HOMEdeğişkenin içeriğine veya ayarlanmadığında, hesap veritabanındaki geçerli kullanıcının giriş dizinine genişler (POSIX'in bu davranışı tanımsız bırakmasından bu yana bir uzantı olarak).

Bu unutulmamalıdır ki ksh88 ve bashsürümleri 4.0 için önce, genişleme liste bağlamlarda (dosya adı nesil) globbing uygulandı tilde:

$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~

Bu olağan durumlarda bir sorun olmamalıdır.

Genişletildiği için, aynı uyarının diğer genişletme şekilleri için de geçerli olduğunu unutmayın.

cd ~

Eğer Çalışmaz $HOMEile başlar -veya içerdiği ..bileşenler. Bu yüzden, herhangi bir fark yaratmanın pek mümkün olmamasına rağmen, kesinlikle şunu söylemek gerekir:

cd -P -- ~

Ya da:

case ~ in
  (/*) cd -P ~;;
  (*) d=~; cd -P "./$d";;
esac

( ,, ... $HOMEgibi değerleri kapsayacak şekilde ) veya-+2

cd

( cdsizi herhangi bir tartışma olmadan ana dizininize götürür)

Diğer mermilerde daha geniş ~açılımlar var. Örneğin zsh, biz var:

  • ~4, ~-, ~-2(Tamamlama) dizin yığınında dizinleri (eğer ettik yerler genişletmek için kullanılan cdönce kadar).
  • dinamik adlı dizinler . Nasıl ~somethinggenişletileceğine karar vermek için kendi mekanizmanızı tanımlayabilirsiniz .

25

Herhangi bir sistemde Bash'in herhangi bir versiyonunda, evet . ~tek başına bir terim olarak genişlemeye tanımlanır:

$ HOME değeri

bu yüzden her zaman $HOMEmevcut kabuğa ne olursa olsun aynı olacaktır . Orada gibi diğer bazı tilde açılımları vardır ~useriçin userbireyin ana dizine, ancak tek bir tırnaksız ~kendi başına her zaman genişleyecek "$HOME".

O Not davranışı arasında ~ve $HOMEbazı durumlarda farklı olabilir: özellikle, eğer $HOMEboşluk (ya da diğer içeren IFS karakterleri), sonra $HOMEise (tırnaksız), birden fazla kelimenin genişleyecek ~her zaman tek kelimedir. ~eşit olarak genleşir "$HOME"(alıntı yapılan).

Özel sorunuzla ilgili olarak:

[[ $HOME == ~ ]]

her zaman doğrudur, çünkü sözcük bölmeyi [[ bastırır . [[ ~ == $HOME ]eğer olmayabilir HOMEsahiptir desen eşleştirme içinde karakterleri, ancak [[ ~ == "$HOME" ]](yani alıntı "$HOME") her zaman doğrudur. Tek parantez içinde kullanmak HOME, boşluk içeren ya da özel karakterlerin değerleri için sözdizimi hatası olabilir . Her mantıklı ana dizin yapılandırma için ~ve "$HOME"aynı ve eşit olarak karşılaştırın.


Stéphane Chazelas, yorumlarda farklı değerlerin verildiği ~ve verildiği bir durumu not etti $HOME: eğer öyleyse unset HOME, ~Bash'i kullandığınızda getpwuidşifre veritabanından bir değer okumak için arayacaksınız . Bu durum, yapılandırma değişikliği yapmamanız koşuluyla hariç tutulur $HOME, ancak burada tamlık için bahsedeceğim.


1
Ancak, /bin/sholmayabilir bash. Posix shteknik özelliklerinden bahsettiğinden emin değilim~
Basile Starynkevitch

1
POSIX belirtir ~. ~Thomson veya Bourne kabuğundaki değildi (zamanlarında olduğu gibi /bin/sh). İçinde rcveya türevlerinde değil (başka bir şey için kullanıldığı yerde)
Stéphane Chazelas

5
Dahil olmak üzere birkaç kabukları içinde basheğer HOMEayarlanmazsa, ~passwd veritabanından kullanıcının ev dizinine şekilde genişler. Yani bu ~, değerine genişlemeyebilecek bir durum $HOME.
Stéphane Chazelas

1
Not olduğunu bashbash4 tilde genişlemesi (deneyin üzerine globbing gerçekleştirmek için kullanılan önce HOME='/*' bash -c 'echo /*'). Yani HOME=/*; [ "$HOME" = ~ ]orada bir hata dönecekti.
Stéphane Chazelas

4
@ cuonglm Kaynak kodunu kontrol ettim. Bu sonuçta çağırır get_current_user_info , hangi kullanan getpwuidtüm platformlarda ama Tandem üzerinde .
Michael Homer
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.