Perché / etc / profile non viene invocato per shell non di accesso?


51

Shell di login e non login definita come:

su - $USER # will give you a login shell
bash # will give you a non-login shell

Il profilo / etc / non viene invocato per shell non di accesso, come quando si avvia konsole (kde). Il profilo / etc / viene invocato solo per le shell di login.

Perché? Per favore, spiega, perché mi piace capire la logica di questo.

Risposte:


100

/etc/profile viene invocato solo per le shell di login perché quello è il suo scopo specifico.

Se si desidera eseguire un comando per shell interattive che non sono shell di accesso e che si sta utilizzando bash, inserirlo in ~/.bashrco /etc/bash.bashrc.

Lo scopo dei file "profilo" è contenere comandi che devono essere eseguiti solo per le shell di accesso. Questi file sono:

  • /etc/profile, eseguito da tutte le shell compatibili con Bourne (inclusi bashe dash) quando avviato come shell di accesso.

  • Script in /etc/profile.d.

    Questo è per le shell in stile Bourne, ma non è codificato nell'eseguibile della shell stessa. Piuttosto, i comandi in /etc/profileli chiamano. Ad esempio, sul mio sistema Ubuntu 12.04, /etc/profileinclude queste righe:

    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i
        fi
      done
      unset i
    fi
    
  • .profile nella home directory dell'utente, eseguito da shell compatibili con Bourne quando avviato come shell di accesso (a meno che non venga sovrascritto, vedere di seguito).

  • .bash_profileo .bash_loginnella home directory dell'utente. Questi sono ignorati da shell diverse da bash. Ma se .bash_profileesiste, lo bashesegue invece di .profile . Se .bash_profilenon esiste ma .bash_loginesiste, viene eseguito invece di .profile.

    (Ma è comune per .bash_profileo .bash_login, quando esiste, essere scritto in modo da * chiamare esplicitamente .profile.)

    Il vantaggio dei file di profilo specifici della shell è che possono contenere comandi o sintassi validi solo per quella shell. Ad esempio, posso usare l' [[operatore di valutazione in .bash_profile/ .bash_loginma se lo utilizzo .profilee quindi eseguo l'accesso dashcome shell, non funzionerà.

Cosa dovrebbe andare nei file "profilo"

I file "profilo" devono contenere comandi che dovrebbero essere eseguiti una sola volta, all'inizio dell'accesso. (Ciò include accessi grafici, poiché iniziano anche con una shell di accesso.) Se una shell è interattiva, l'utente che la esegue è probabilmente connesso e quindi probabilmente ha un antenato (che l'ha avviata o avviata ciò che l'ha avviata, o avviato quello, ecc.) che era una shell di accesso.

Potresti voler eseguire un comando una sola volta perché:

  1. non c'è motivo di eseguirlo più di una volta per accesso, sarebbe inefficiente o
  2. produrrebbe un risultato indesiderato, eseguendolo più di una volta per accesso.

Come esempio della seconda situazione, in cui si verificherebbe un risultato indesiderato, considerare queste righe, che appaiono per impostazione predefinita in ogni utente ~/.profile:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Supponiamo che SSH sia entrato, abbia eseguito un'altra shell (diciamo, zsh), ad un certo punto ho scoperto che volevi tornare temporaneamente bashma mantenere il tuo ambiente (quindi eseguito di bashnuovo mentre sei dentro zsh), quindi mceseguire un programma del genere che esegue una shell come parte della sua interfaccia. Se binesiste nella tua cartella home e il tuo nome utente è james, quello PATHnella shell più interna è qualcosa del tipo:

/home/james/bin:/home/james/bin:/home/james/bin:/home/james/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Questo è inefficiente e (molto più importante) rende difficile capire il contenuto di PATH.

Questo non è affatto un disastro, però. Per quanto ne so, se ogni shell interattiva provenga da "profili" di file, nella configurazione predefinita non accadrebbe nulla di terribile . Tuttavia, poiché lo scopo dei file "profilo" è contenere comandi da eseguire una sola volta per accesso , un utente o un amministratore può aggiungere comandi a un profilo che deve essere eseguito solo quando si avvia una shell di accesso.

Dove mettere i comandi per ogni shell interattiva da eseguire

Se stai usando bash, ci sono file per i comandi che devono essere eseguiti in ogni shell interattiva:

  • /etc/bash.bashrc
  • .bashrc nella home directory dell'utente.

Questo è più comunemente usato per i comandi che

  1. influisce solo sull'ambiente della shell in cui sono in esecuzione, nemmeno sulle shell secondarie, oppure
  2. dovrebbe essere eseguito anche quando questa non è la shell di login.

Ad esempio, il completamento della scheda da riga di comando dovrebbe generalmente essere abilitato indipendentemente bashdalla shell di login. Quindi questo appare in ~/.bashrc:

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

Lì, si applicano entrambi 1 e 2 : questo non si ripercuote su altre shell eseguite all'interno di questa e il completamento della scheda dovrebbe funzionare bashanche se ho effettuato l'accesso con una shell diversa.

Dove inserire i comandi per le shell di accesso e le shell interattive non di accesso

Se si utilizza bashe si desidera eseguire un comando in shell di accesso e shell interattive e che non sono shell di accesso, è generalmente sufficiente inserirlo /etc/bash.bashrco~/.bashrc . Questo perché, per impostazione predefinita, /etc/profileed ~/.profileeseguirli esplicitamente. Ad esempio, ~/.profileha:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

(Allo stesso modo, /etc/profilefonti /etc/bash.bashrcper bash.)

Pertanto, entrambi i file "profilo" e "rc" vengono eseguiti all'avvio di una bashshell interattiva (indipendentemente dal fatto che si tratti di una shell di accesso).

Dove mettere i comandi da eseguire in shell non interattive

Probabilmente non si desidera specificare alcun comando per l'esecuzione di tutte le shell non interattive; verrebbero eseguiti ogni volta che viene eseguito uno script (a condizione che lo script venga eseguito dalla shell configurata per eseguirli).

Ciò può causare rotture sostanziali. Se hai intenzione di farlo, e non c'è un account amministratore sul sistema oltre a quello che stai usando, potresti crearne uno; ciò può semplificare la correzione degli errori.

In bash, i file "rc" vengono effettivamente eseguiti indipendentemente dal fatto che la shell sia interattiva o meno . Tuttavia, nella parte superiore dicono:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Quindi, se hai bisogno di comandi da eseguire automaticamente anche in shell non interattive come quelle che eseguono per eseguire script, puoi aggiungere i tuoi comandi prima di quelle righe.

Avvio di una shell di accesso

L'accesso avvia una shell di accesso. Se si desidera un guscio iniziato dopo che per comportarsi come una shell di login, avviarlo con la -lbandierina (sta per l ogin ). Per esempio:

Questo è il modo migliore per avviare una shell di accesso (senza accedere) a meno che non si desideri avviarne uno come un altro utente. Quindi, utilizzare:

  • sudo -iper root(utilizzare sudo -sper una shell root interattiva e senza accesso)
  • sudo -u username -i per qualsiasi utente
  • su - usernameper i non rootutenti (utilizzare per una shell root interattiva, senza accesso)su username

Che cos'è una shell di accesso iniziale ?

Una shell di login iniziale è la stessa di una shell di login . Ovunque questa risposta dice "shell di accesso", potrebbe dire "shell di accesso iniziale" (tranne in questa sezione, che avrebbe già smesso di avere senso).

Uno dei motivi del termine inital login shell è che anche la shell di accesso viene utilizzata in un altro senso - per identificare quale programma viene utilizzato come shell che viene eseguita accedendo. Questo è il senso della shell di login usata per dire:

  • " La shell di accesso predefinita di OpenBSD è ksh; in Ubuntu lo è bash."
  • "Puoi cambiare la tua shell di login con chsh."

Ulteriori letture


4
Una delle migliori risposte a qualsiasi domanda su qualsiasi sito Stack Exchange.
Mark E. Haase,

1
> I file "profilo" devono contenere comandi che dovrebbero essere eseguiti una sola volta, all'inizio dell'accesso. (Ciò include accessi grafici, poiché iniziano anche con una shell di accesso.) No no no no no! Assolutamente no! Tutte le shell simili a bourne leggono solo .profile nelle sessioni interattive della shell di login , ovvero quelle avviate con l'opzione -i o quelle connesse a un terminale di controllo (nessuna delle quali è vera se la shell è stata avviata da un display manager). Il motivo è vero perché il punto di questo file è configurare il terminale dell'utente , non solo il suo ambiente. Se un display manager tr

Eliah, ho riprodotto il resto del commento di Derek qui, ma ho lasciato il moncone sopra così lui riceverà la tua notifica di risposta, anche se non sarà in grado di rispondere a causa dei requisiti di reputazione. Tuttavia, gli ho dato l'accesso in scrittura alla chat room sopra.
Seth,

1
In bash, the "rc" files are actually run whether the shell is interactive or not. non è corretto. /etc/bash.bashrc è attivato da /etc/bash.profile.
Okwap

OKWAP è giusto, file rc non venga invocato in shell non interattiva, questo questo è più succinta e precisa.
Nick Allen,
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.