Come fa una shell a sapere a casa (e)?


25

Ogni shell ha una variabile d'ambiente $ HOME impostata (es:) /Users/lotolo. Se sono sotto csh posso unsetenv HOMEe ancora se lo faccio cdsarò a casa mia. L'ho provato anche su bash ( unset HOME) ed è lo stesso comportamento. Quindi, come fa la shell a sapere dove si trova la mia / other_user home? Dove legge quei valori?

Questo non è un duplicato dal momento che la mia domanda non è: come faccio io so, ma come fa il guscio sapere HOME. E questo comportamento è esteso anche ad altri utenti.


1
@StephenKitt, no non un duplicato. Qui stiamo parlando del comportamento della shell per la home directory dell'utente corrente.
Stéphane Chazelas,

Nel caso semplice di /etc/passwd. Alcuni sistemi possono archiviare tali informazioni in LDAP, server NIS, ecc.
Satō Katsura,

1
I programmi (comprese le shell) chiamano semplicemente getpwuid(3)o simili. Alcuni sistemi possono essere configurati per "reindirizzare" getpwuid(3)per recuperare informazioni da /etc/passwd, LDAP, NIS, NIS + ecc.
Satō Katsura,

@StephenKitt, vedi la mia risposta
Stéphane Chazelas,

1
@ GAD3R, vedi la discussione sopra, StephenKitt aveva già indicato lo stesso duplicato (che da allora ha ritirato), ma discuto sopra (e vedi anche la mia risposta) che non è un duplicato.
Stéphane Chazelas,

Risposte:


33

Nel caso di cshe tcsh, registra il valore della $HOMEvariabile al momento dell'avvio della shell ( nella sua $homevariabile come notato da @JdeBP ).

Se lo disattivi prima di iniziare csh, vedrai qualcosa di simile:

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

Per bash(e la maggior parte delle altre conchiglie tipo Bourne), vedo un comportamento diverso dal tuo.

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

Il contenuto della $HOMEvariabile viene inizializzato dal processo di accesso in base alle informazioni memorizzate nel database utente in base al nome utente .

Le informazioni sul nome utente stesso non sono sempre disponibili. Tutto ciò che una shell può sapere con certezza è l'ID utente del processo che lo sta eseguendo e diversi utenti (con directory home diverse) possono condividere lo stesso ID utente.

Quindi, una volta $HOMEsparito, non esiste un modo affidabile per ripristinarlo.

Interrogare il database utente (con getpwxxx()API standard) per la directory home del primo utente che ha lo stesso uid di quello che esegue la shell sarebbe solo un'approssimazione (per non parlare del fatto che il database utente potrebbe essere cambiato (o la home la directory viene definita come valore singolo) dall'inizio della sessione di accesso).

zsh è l'unica shell che conosco che lo fa:

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

Tutte le altre shell che ho provato si lamentano di quella HOME non impostata o la usano /come valore home predefinito.

Tuttavia, si tratta di un comportamento diverso fish, che sembra richiedere al database il nome utente memorizzato $USERse presente o fare un getpwuid()se no:

$ 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) +++

SEGV quando l'utente non esiste ( 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
Suppongo che possiamo segnalare questo problema! Molto bella risposta tra l'altro, grazie!
LotoLo,

1
@LotoLo, sì, sono occupato a costruire con fishla testa dev git per vedere se il bug è presente. Modificare. Sì.
Stéphane Chazelas,

Ora sono curioso: quale variabile d'ambiente rende la shell estremamente user-friendly se non impostata? PATH? TERM? USER?
user1024

C'è una strana linea qui: "sarebbe solo un'approssimazione ..." Anche le parentesi non si allineano in quel paragrafo. Cosa doveva essere?
muru,

1
@muru Querying the user database... would only be...non è così chiaro
edc65

6

Quindi come fa la shell a sapere dove si trova la mia / other_user home?

Non Non stai semplicemente eseguendo l'esperimento correttamente. Come si può vedere dal manuale della shell C, il cdcomando cambia nel valore della homevariabile se fornito senza argomenti. Se questa variabile non è impostata, non sa dove cambiare directory e stampa un errore:

macchina: ~> imposta home = /
macchina: / home / utente> cd
macchina: ~> disinserita home
macchina: /> cd
cd: nessuna home directory
macchina: /> 

Hai annullato la variabile sbagliata. Non è HOMEla variabile d'ambiente, è homela variabile interna della shell C (inizializzata dal valore della prima all'avvio della shell, ma per il resto una variabile indipendente a sé stante).


no su csh (almeno nella mia versione: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") è la variabile HOME che porta il valore di home. Ma come ha detto @Stephane Chazelas, devo disinserire la variabile prima di avviare la shell poiché imposterà il valore HOME all'avvio.
LotoLo,

Quanto sopra è la shell C, che ho eseguito su una comoda macchina OpenBSD, e dimostra il suo comportamento. Non è nemmeno la shell TENEX C (sebbene ciò si comporti allo stesso modo).
JdeBP,

Sì, l'ho visto ... Ho digitato cshma a quanto pare è aliastcsh
LotoLo

0

Il sistema ha impostato la variabile HOME al momento dell'accesso come percorso della home directory dell'utente. È impostato da

  • gdm, kdm o xdm per sessioni grafiche.
  • accedere alle sessioni console, telnet e rlogin
  • sshd per connessioni SSH

Puoi cambiarne il valore ma fai attenzione perché .bashrc, .profile, .xinitrc, ecc. Non verranno letti se non si trovano nella directory home.


Ma posso annullarlo ($ HOME) ... giusto? E come fa a sapere dov'è la casa di un altro utente?
LotoLo,

1
puoi aggiornarlo usando il usermod -d HOME_DIRcomando, quando viene creato un nuovo utente. la home predefinita è / home / $ username ed è determinata dal programma di login.
Dababi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.