Dove viene definita la shell di accesso?


16

Stavo leggendo la differenza tra sudo -i/-s qui . Dopo aver usato il comando shoptsi nota che all ( sudo su/sudo -i/sudo -s) $SHELLstanno fornendo gli stessi risultati, ma i shoptrisultati del comando sono diversi.

Quindi, come viene definita la shell di login e non login?

Da dove shoptottenere il risultato?

Perché non è correlato $SHELL?

sudo su

givinv@87-109:~$ sudo su
root@87-109:/home/givinv# 
root@87-109:/home/givinv# 
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv# 
root@87-109:/home/givinv# exit
givinv@87-109:~$ 

sudo -i

givinv@87-109:~$ sudo -i
root@87-109:~# 
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

sudo -s

root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

7
Un problema è che "shell di accesso" ha due significati: 1. È un'istanza di una shell avviata in un modo specifico che fa cose specifiche (come lettura .profileo equivalenti), e 2. È la shell che dovrebbe essere avviata all'accesso per un utente, come definito in /etc/passwdo equivalente. $SHELLcontiene il secondo, i tuoi shoptoutput si occupano del primo. In genere, quando la shell in (2) viene avviata all'accesso, viene avviata nel modo specifico necessario per (1), da cui la conflazione dei significati.
Muru,

1
La spiegazione di @muru è buona. ad esempio se si SSH nel computer da un computer remoto. / usr / sbin / sshd sul tuo sistema eseguirà il fork di una shell definita da $SHELL(e la collegherà a uno pseudo terminale) che a sua volta è definito nella voce / etc / passwd. questa shell è una shell di login e può essere testata con if [[ -o login ]]; then echo "I am a login shell"; fi. essendo una shell di login, eseguirà le attività appropriate per una nuova sessione. es. sorgente ~/.zprofileo simile che potrebbe impostare variabili d'ambiente e qualsiasi codice shell personalizzato che potresti voler eseguire in questo momento
the_velour_fog

Risposte:


17

TL; DR :

  • Dove viene definita la shell di accesso? In /etc/passwd.
  • Sono sudo su/ sudo su -/ sudo -i/ sudo -sstessa? No, generano tutti una shell ma in modo diverso e in contesti diversi.
  • Cosa fa $SHELL? Basta dire la shell predefinita, come in /etc/passwd.

Risposta effettiva :

Prima di tutto, è importante ricordare che shoptè specifico per Bash. Ad esempio, sono un mkshutente shell e non ha shopt, proprio come kshnon lo è.

Quindi, cosa login_shelldovrebbe rappresentare esattamente ? Da man bash:

login_shell

La shell imposta questa opzione se viene avviata come shell di accesso

Questo è il punto chiave. sudo -i, come già sapete dalla risposta precedente che avete letto, dovrebbe simulare il login iniziale. Ecco perché i shoptrapporti login_shell on per questa opzione. Pensa a questo come se sudo -iforzasse la shell a passare attraverso i file che dovrebbero apparire solo durante un processo di login (che non provengono da shell interattive).

In altri casi, stai già eseguendo un'istanza di una shell, quindi in primo luogo non può essere la shell di accesso e lo scopo delle opzioni è diverso. sudo -slegge semplicemente $SHELL(che dovrebbe rappresentare la shell predefinita come impostata in /etc/passwd) variabile e la esegue con il privilegio di root. Ciò equivale a fare sudo $SHELLo sudo mksho sudo bash(qualunque sia il caso in cui si usi).

Ricordi di aver detto che sono mkshutente? Guarda questo:

$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi: 

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id 
uid=0(root) gid=0(root) groups=0(root)

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU

Quello che vedi è che è sudo -ssaltato dalla bashmia mkshshell, con il prompt caratteristico che ho impostato per questo. E naturalmente, poiché non si tratta di un'azione di accesso, in bashquanto segnalerebbe che la shell viene generata come istanza di shell non di accesso. Nel mio caso, tuttavia, vedi che $-non c'è una lettera llì, che sarebbe lì se fosse un'istanza della shell di accesso.

Infine, la stessa idea si applica a sudo sue sudo su -. Successivamente viene generata l'istanza della shell di accesso (ovvero, verranno eseguiti file specifici necessari per l'accesso) e la precedente genera solo shell interattive (ovvero, i file di accesso non vengono eseguiti).

bash-4.3$ sudo su
[sudo] password for xieerqi: 
root@eagle:/home/xieerqi# shopt login_shell
login_shell     off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi: 
$ shopt login_shell
login_shell     on

Quindi tecnicamente shopt login_shellnon ha alcuna relazione con nessuno $SHELL. Pensala in questo modo: il suo scopo è mostrare come corre Bash. $SHELLdovrebbe riflettere solo ciò che ti è stato assegnato /etc/passwd.

Per quanto riguarda la differenza tra shell di login e shell di non login, questa risposta è stata spiegata da Gilles altamente rispettato su unix.stackexchange.com .


Divertimento aggiuntivo

Ecco qualcosa di divertente che puoi provare. Come forse già saprai, verrà eseguita una shell di accesso .profile(e .bashrcpoiché Ubuntu .profile è configurata per farlo ), ma l'inferno senza login eseguirà solo .bashrcfile. Quindi possiamo testare con echoquale di questi comandi viene eseguita una shell di accesso e quale no, e ci aspettiamo due righe echoper la shell di accesso e solo una per la non login.

$ echo "echo 'hi,i am .profile'"  >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~# 

Abbastanza opportunamente, quelli con due linee di output avranno login_shellimpostato su on.


Grazie @Serg e @Zanna. Ora circa $SHELLe login_shell/non-login_shellsono stato chiarito. Ma da dove shoptottenere i dettagli? Viene da echo $0?
prado,

1
@prado Direi di sì, dato che il primo carattere di $0viene usato per indicare se una shell è o meno una shell di login, quindi se shoptsi controlla quella variabile - certo, è perfettamente accettabile. Tuttavia, c'è probabilmente più di quanto sembri. shoptprobabilmente per questa domanda, non ho una risposta difficile, dal momento che non conosco bene il codice sorgente di bash.
Sergiy Kolodyazhnyy,

@prado Bash può essere avviato come shell di login con il primo carattere di $ 0 -, oppure usando l' -lopzione.
muru,

@prado puoi leggere l'invocazione e le opzioni di bash nella pagina man. ad esempio la sezione SHELL BUILTIN COMMAND dice che il login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.modo shopt login_shellin cui bash sembra farti scoprire - programmaticamente come sapere come è stato avviato. l'altro sarebbe[[ -o login ]]
the_velour_fog

11

Come spiega @Serg in questa risposta su come dire quale shell si sta eseguendo , la SHELLvariabile è solo la shell predefinita dell'utente corrente come letto da /etc/passwd:

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash

quindi se echo $SHELLtornerò sempre /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

O meno la shell è una shell di login, è un sh ell opt ioni determinato al momento si avvia la shell. Il programma shell memorizza queste informazioni insieme a tutte le altre impostazioni e variabili. Il shoptcomando fornisce un modo per vedere queste informazioni e, se possibile per l'opzione in questione, impostarle o disinserirle (questo non è il caso per il login_shellquale, ovviamente, dipende dal processo usato per avviare la shell)

Le sudoopzioni del programma determinano come verranno avviati questi diversi tipi di shell root:

inserisci qui la descrizione dell'immagine


1
Buona spiegazione Penso che tu abbia spiegato cosa shopte login_shelldovresti rappresentare molto meglio di quello nella mia risposta.
Sergiy Kolodyazhnyy,

@Serg grazie :) Penso che la tua spiegazione sia più approfondita :)
Zanna,

3

man bash:

Una shell di login è quella il cui primo carattere dell'argomento zero è a -, oppure uno è iniziato con l' --loginopzione.

man login:

Il valore per $HOME, $SHELL[...] è impostato in base ai campi appropriati nella voce della password.

In breve:

  • Una shell è una shell di accesso se è stata invocata come shell di accesso.
  • La variabile d'ambiente $SHELLè impostata login, ad esempio, dal o dal programma che invoca su. La shell stessa non lo imposta.
  • shopt mostra le opzioni di shell attualmente attive.
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.