GNU/Linux >> Linux Esercitazione >  >> Linux

Perché le shell interattive sulle shell di accesso Osx sono predefinite?

In Linux e, per quanto ne so, in tutti i sistemi Unix, gli emulatori di terminale eseguono shell interattive senza login per impostazione predefinita. Ciò significa che, per bash, la shell avviata:

Quando viene avviata una shell interattiva che non è una shell di accesso, bash legge ed esegue i comandi da /etc/bash.bashrc e ~/.bashrc , se questi file esistono. Questo può essere inibito usando il --norc opzione.

Il --rcfile l'opzione file forzerà bash a leggere ed eseguire comandi da file invece di /etc/bash.bashrc e ~/.bashrc .

E per le shell di accesso:

Quando bash viene invocato come shell di accesso interattiva o come shell non interattiva con --login opzione, legge ed esegue prima i comandi dal file /etc/profile , se quel file esiste. Dopo aver letto quel file, cerca ~/.bash_profile , ~/.bash_login e ~/.profile , in quest'ordine, e legge ed esegue i comandi dal primo che esiste ed è leggibile.

Il --noprofile l'opzione può essere utilizzata all'avvio della shell per inibire questo comportamento.

Su OSX, tuttavia, la shell predefinita (che è bash) avviata nel terminale predefinito (Terminal.app) in realtà genera ~/.bash_profile o ~.profile ecc. In altre parole, si comporta come una shell di accesso.

Domanda principale :Perché la shell interattiva predefinita è una shell di accesso su OSX? Perché OSX ha scelto di farlo? Ciò significa che tutte le istruzioni/tutorial per cose basate su shell che menzionano la modifica di cose in ~/.bashrc fallirà su OSX o viceversa per ~/.profile . Tuttavia, mentre molte accuse possono essere rivolte ad Apple, l'assunzione di sviluppatori incompetenti o idioti non è una di queste. Presumibilmente, avevano una buona ragione per questo, quindi perché?

Domande secondarie:Terminal.app esegue effettivamente una shell di accesso interattiva o ha cambiato il comportamento di bash? È specifico di Terminal.app o è indipendente dall'emulatore di terminale?

Risposta accettata:

Il modo in cui è supposto il lavoro è che, nel momento in cui ricevi un prompt della shell, entrambi .profile e .bashrc sono stati eseguiti. I dettagli specifici su come arrivare a quel punto sono di secondaria importanza, ma se uno dei file non venisse eseguito affatto, avresti una shell con impostazioni incomplete.

Il motivo per cui gli emulatori di terminale su Linux (e altri sistemi basati su X) non ne hanno bisogno per eseguire .profile stessi è che normalmente sarà già stato eseguito quando hai effettuato l'accesso a X. Le impostazioni in .profile dovrebbero essere del tipo che può essere ereditato dai sottoprocessi, a patto che venga eseguito una volta al momento dell'accesso (ad es. tramite .Xsession ), non è necessario rieseguire qualsiasi altra sottoshell.

Come spiega la pagina wiki di Debian collegata da Alan Shutko:

"Perché è .bashrc un file separato da .bash_profile , poi? Ciò avviene per ragioni prevalentemente storiche, quando le macchine erano estremamente lente rispetto alle workstation odierne. Elaborazione dei comandi in .profile o .bash_profile potrebbe richiedere molto tempo, specialmente su una macchina in cui gran parte del lavoro doveva essere svolto da comandi esterni (pre-bash). Quindi i difficili comandi di configurazione iniziale, che creano variabili d'ambiente che possono essere passate ai processi figli, sono inseriti in .bash_profile . Le impostazioni transitorie e gli alias che non vengono ereditati vengono inseriti in .bashrc in modo che possano essere riletti da ogni subshell."

Tutte le stesse regole valgono anche su OSX, tranne per una cosa:la GUI di OSX non esegue .profile quando accedi, apparentemente perché ha il suo metodo per caricare le impostazioni globali. Ma ciò significa che un emulatore di terminale su OSX lo fa è necessario eseguire .profile (dicendo alla shell che si avvia che è una shell di accesso), altrimenti finiresti con una shell potenzialmente paralizzata.

Correlati:come modificare la shell cron (da sh a bash)?

Ora, una specie di sciocca particolarità di bash, non condivisa dalla maggior parte delle altre shell, è che non eseguirà automaticamente .bashrc se è stato avviato come shell di accesso. La soluzione standard per questo è includere qualcosa come i seguenti comandi in .bash_profile :

[[ -e ~/.profile ]] && source ~/.profile    # load generic profile settings
[[ -e ~/.bashrc  ]] && source ~/.bashrc     # load aliases etc.

In alternativa, è possibile non avere .bash_profile e includi semplicemente del codice specifico di bash nel generico .profile per eseguire .bashrc se necessario.

Se l'impostazione predefinita di OSX .bash_profile o .profile non fallo, allora è probabilmente un bug. In ogni caso, la soluzione corretta è semplicemente aggiungere quelle righe a .bash_profile .

Modifica: Come osserva Strugee, la shell predefinita su OSX era tcsh, il cui comportamento è molto più sano sotto questo aspetto:quando viene eseguito come shell di login interattiva, tcsh legge automaticamente entrambi .profile e .tcshrc / .cshrc , e quindi non ha bisogno di soluzioni alternative come .bash_profile trucco mostrato sopra.

Sulla base di ciò, sono sicuro al 99% che l'errore di OSX nel fornire un .bash_profile predefinito appropriato è perché, quando sono passati da tcsh a bash, la gente di Apple semplicemente non ha notato questa piccola verruca nel comportamento di avvio di bash. Con tcsh, non erano necessari trucchi del genere:avviare tcsh come shell di accesso da un emulatore di terminale OSX Just Plain Works e fare la cosa giusta senza tali kluges.


Linux
  1. Differenza tra shell di accesso e shell non di accesso?

  2. Perché Bashrc controlla se la shell corrente è interattiva?

  3. Perché una shell di accesso "sudo -i" interrompe un argomento della stringa di comando Here-doc?

  4. Processi in una sessione in una shell interattiva vs in uno script?

  5. Perché posso accedere con password parziali??

Perché $shlvl inizia al livello 2 nelle shell non di accesso ma al livello 1 nelle shell di accesso in Rhel 7?

Che cos'è Login Shell in Linux?

8 tipi di shell Linux

Modifica della shell predefinita in Linux

Perché il mio accesso SSH è lento?

Perché l'utente "bin" ha bisogno di una shell di login?