Bir kabuk ev (ler) i nasıl tanıyor?


25

Her kabuğun $ HOME set ortam değişkeni vardır (örneğin:) /Users/lotolo. Eğer csh altındaysam yapabilirim unsetenv HOMEve hala yaparsam cdevimde olacağım. Bunu bash ( unset HOME) üzerinde de test ettim ve aynı davranış. Öyleyse, kabuk / other_user evimin nerede olduğunu nereden biliyor? Bu değerleri nerede okuyor?

Bu sorum nasıl olmadığından bir kopya değil ben biliyorum ama nasıl oluyor kabuk know- HOME. Ve bu davranış diğer kullanıcılara da yayılmıştır.


1
@StephenKitt, kopya değil. Burada, mevcut kullanıcının giriş dizini için kabuk davranışından bahsediyoruz.
Stéphane Chazelas

Dan basit durumda /etc/passwd. Bazı sistemler bu bilgileri LDAP’de, NIS sunucularında vb.
Saklayabilir

1
Programlar (kabukları dahil) sadece arayın getpwuid(3)veya benzerleri. Bazı sistemler "yeniden rota" için yapılandırılabilir getpwuid(3)bilgi almak için /etc/passwdvs LDAP, NIS, NIS +,
Satō Katsura

@StephenKitt, cevabımı gör
Stéphane Chazelas

1
@ GAD3R, yukarıdaki tartışmaya bakınız, StephenKitt zaten aynı yinelemeye (o zamandan beri geri çekildi) işaret etmişti , ama yukarıda ((ayrıca cevabımı da görüyorum) yinelemenin olmadığını iddia ettim.
Stéphane Chazelas

Yanıtlar:


33

Durumunda cshve tcshbu değerini kaydeder $HOME(kabuk başlatıldığı zaman değişkeni onun içinde $home@JdeBP tarafından belirtildiği gibi değişken ).

Başlamadan önce cshayırırsanız, şöyle bir şey görürsünüz:

$ (unset HOME; csh -c cd)
cd: No home directory.

İçin bash(ve Bourne gibi kabuklarına diğer çoğu), ben seninkinden daha farklı bir davranış bakın.

bash-4.4$ unset HOME; cd
bash: cd: HOME not set

İçeriği $HOMEdeğişken kullanıcı karşı kullanıcı veritabanında saklanan bilgilere dayanarak giriş işlemi ile bir sıfırlanır isim .

Kullanıcı adıyla ilgili bilgiler her zaman kullanılamaz. Kesin olarak bir kabuğun tüm bildiği, onu çalıştıran işlemin kullanıcı kimliğidir ve birçok kullanıcı (farklı ev dizinleri ile) aynı kullanıcı kimliğini paylaşabilir.

Yani, bir kez $HOMEgitti, onu geri almak için güvenilir bir yolu yoktur.

getpwxxx()Kabuğu çalıştıran ile aynı kullanıcı kimliğine sahip olan ilk kullanıcının giriş dizini için kullanıcı veritabanını ( standart API ile) sorgulamak yalnızca bir yaklaşım olacaktır (kullanıcı veritabanının değişmiş olabileceği gerçeğinden bahsetmeden değil) dizini, tek seferlik bir değer olarak tanımlanıyor).

zsh Bunu bildiğim tek kabuk:

$ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd'
zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697)      = 0x7f95992fddc0
/home/chazelas
+++ exited (status 0) +++

Çalıştığım diğer tüm kabukları, bu dengesiz HOME hakkında şikayet ediyor veya /varsayılan bir ev değeri olarak kullanıyor.

Yine de farklı bir davranış vardır fish, ki bu veritabanında depolanan kullanıcı adı için veritabanını sorgulamış gibi görünüyor $USERya da getpwuid()eğer değilse:

$ env -u HOME USER=bin ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwnam("bin")  = 0x7fd2beba3d80
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
--- SIGCHLD (Child exited) ---
/bin
+++ exited (status 0) +++


$ env -u HOME -u USER ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwuid(1000, 0x7f529eb4fb28, 0x12d8790, 0x7f529e858697) = 0x7f529eb51dc0
fish->getpwnam("chazelas")                                      = 0x7f529eb51d80
--- SIGCHLD (Child exited) ---
--- SIGCHLD (Child exited) ---
/home/chazelas
+++ exited (status 0) +++

Kullanıcı olmadığında SEGV ( https://github.com/fish-shell/fish-shell/issues/3599 ):

$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault  env -u HOME USER=foo fish -c ''

2
Sanırım bu sorunu bildirebiliriz! Çok güzel cevap btw, teşekkürler!
LotoLo

1
@LotoLo, evet, fishböcek de orada olup olmadığını görmek için dev git baş ile inşa meşgul . Düzenle. Evet öyle.
Stéphane Chazelas

Şimdi merak ediyorum: Hangi ortam değişkeni, eğer ayarlanmamışsa, kabuğu maksimum derecede kullanıcı dostu kılıyor? PATH? TERM? USER?
user1024,

Burada garip bir satır var: "sadece bir yaklaşım olurdu ..." Parantezler de bu paragrafta sıralanmıyor. Ne olması gerekiyordu?
muru,

1
@muru Querying the user database... would only be...gerçekten çok net değil
edc65

6

Öyleyse, kabuk / other_user evimin nerede olduğunu nereden biliyor?

Öyle değil. Sadece deneyi uygun şekilde yapmıyorsun. C kabuk kılavuzundan görebileceğiniz gibi , herhangi bir argüman verilmezse , cdkomut homedeğişkenin değerine değişir . Bu değişken ayarlanmamışsa, dizinin nereye değiştirileceğini bilmiyor ve bir hatayı yazdırıyor:

makine: ~> ev ayarlamak = /
makine: / ev / kullanıcı> cd
makine: ~> ev ağlamak
makine: /> cd
cd: Giriş dizini yok
makine: /> 

Yanlış değişkeni ayarladınız. HOMEOrtam değişkeni değildir , homeC kabuğunun iç değişkenidir (kabuk başladığında önceki değerden başlatılır, ancak aksi halde kendi başına bağımsız bir değişkendir).


csh'de hayır (en azından benim sürümümde: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") bu, evin değerini taşıyan HOME değişkenidir. Fakat @Stephane Chazelas'ın dediği gibi, kabuk başlatılmadan önce değişkeni ayarlamalıyım, çünkü HOME değerini başlangıçta ayarlayacaktır.
LotoLo

Yukarıda ise ben kullanışlı bir OpenBSD makinede ran C kabuk, ve bunun davranışı gösterir. TENEX C kabuğu bile değil (aynı şekilde davransa da).
JdeBP,

Evet gördüm ... cshtcsh
Yazdım

0

Sistem, giriş sırasında HOME değişkenini kullanıcının giriş dizininin bir yolu olacak şekilde ayarlar. Tarafından ayarlanır

  • Grafik oturumları için gdm, kdm veya xdm.
  • Konsolda oturum açma, telnet ve rlogin oturumları
  • SSH bağlantıları için sshd

Değeri değiştirebilirsiniz, ancak .bashrc, .profile, .xinitrc, vb ana dizinde değilse okunmayacağından dikkat edin.


Ama onu ayarlayabiliyorum ($ HOME) ... değil mi? Ve başka bir kullanıcının evi nerede olduğunu nasıl biliyor?
LotoLo

1
usermod -d HOME_DIRYeni bir usre oluşturulduğunda komutu kullanarak güncelleyebilirsiniz . varsayılan ev / home / $ kullaniciadi adıdır ve giriş programı tarafından belirlenir.
Dababi
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.