Scegliendo tra .bashrc, .profile, .bash_profile, ecc. [Duplicato]


197

Questa domanda ha già una risposta qui:

Questo è imbarazzante, ma dopo molti anni di utilizzo di sistemi POSIX a tempo pieno, ho ancora difficoltà a capire se una personalizzazione della shell dovrebbe andare in .bashrc, .profileo da qualche altra parte. Per non parlare di alcuni dei file di configurazione specifici del sistema operativo come .pam_environment.

Sì, so come risolvere i problemi della documentazione e apprendere quando ogni file è o non è caricato. Quello che mi chiedo è se qualcuno ha messo insieme linee guida complete su come decidere in quale file inserire un determinato tipo di personalizzazione.


6
questa domanda non deve essere contrassegnata come duplicata perché il motivo è .profile non è disponibile nella domanda aggiunta.
Premraj,

Risposte:


222

TL; DR:

  • ~/.bash_profiledovrebbe essere super-semplice e basta caricare .profilee .bashrc(in quell'ordine)

  • ~/.profileha le cose NON specificamente correlate a bash, come variabili d'ambiente ( PATHe amici)

  • ~/.bashrcha tutto ciò che desideri da una riga di comando interattiva. Prompt dei comandi, EDITORvariabile, bash alias per il mio uso

Alcune altre note:

  • Tutto ciò che dovrebbe essere disponibile per applicazioni grafiche O per sh (o bash invocato come sh) DEVE essere in~/.profile

  • ~/.bashrc non deve emettere nulla

  • Tutto ciò che dovrebbe essere disponibile solo per accedere alle shell dovrebbe entrare ~/.profile

  • Assicurarsi che ~/.bash_loginnon esista.


3
+1, questo consente ~/.profiledi impostare correttamente l'ambiente per servizi come GDM / LightDM / LXDM che eseguono esplicitamente / bin / sh.
Grawity,

12
Le mie .bashrcuscite sono un sacco di cose, puoi commentarle? In particolare, dove devo inserire l'output di saluto?
Calimo,

14
@Calimo: rendilo in uscita solo in modalità interattiva. Puoi provarlo usando [[ $- == *i* ]], cioè, cercando 'i' nella $-variabile speciale . Ovviamente, importa solo in primo luogo su sistemi in cui bash è compilato per essere letto .bashrcin modalità non interattiva. (Cioè, Debian ma non Arch.) Ma è una causa frequente di misteriosi messaggi di errore quando si tenta di connettersi utilizzando sftpo scpo strumenti simili.
Grawity,

4
Ora devo sapere- perché non dovrebbe esistere .bash_login? Che cosa fa?
tedder42

11
@ tedder42: fa lo stesso di .bash_profilee .profile. Ma bash legge solo il primo su tre. Significa che se hai un .bash_login, allora entrambi .profilee .bash_profilesaranno misteriosamente ignorati.
Grawity,

54

Nel corso degli ultimi anni, ho avuto un sacco di tempo da perdere, così ho ho studiato questo per un po 'più di soli 10 minuti. Non ho idea se questo è il layout migliore, è solo uno che funziona correttamente in quasi tutti i casi.

I requisiti:

  • ~/.profile deve essere compatibile con qualsiasi / bin / sh - questo include bash, dash, ksh, qualunque altra cosa una distribuzione possa scegliere di usare.

  • Le variabili di ambiente devono essere inserite in un file letto sia dagli accessi della console (ovvero una shell 'login') sia dagli accessi grafici (ovvero i gestori di visualizzazione come GDM, LightDM o LXDM).

  • Non ha molto senso avere entrambi ~/.profile e ~/.bash_profile. Se quest'ultimo manca, bash utilizzerà felicemente il primo e qualsiasi linea specifica per bash può essere protetta con un controllo per $BASHo $BASH_VERSION.

  • La separazione tra *profilee *rcè che il primo è usato per shell di 'login', e il secondo ogni volta che si apre una finestra terminale. Tuttavia, bash in modalità 'login' non ha origine ~/.bashrc, quindi ~/.profiledeve farlo manualmente.

La configurazione più semplice sarebbe:

  • Avere un ~/.profileche imposta tutte le variabili d'ambiente (eccetto quelle specifiche di bash), forse stampa una riga o due, quindi i sorgenti ~/.bashrcse vengono eseguiti da bash, attenendosi alla sintassi sh-compatibile altrimenti.

    export TZ = "Europa / Parigi"
    export EDITOR = "vim"
    if ["$ BASH"]; poi
        . ~ / .Bashrc
    fi
    uptime
    
  • Avere un ~/.bashrcche esegue qualsiasi installazione specifica della shell, sorvegliata con un controllo per la modalità interattiva per evitare di interrompere cose come sftpsu Debian (dove bash è compilato con l'opzione per caricare ~/.bashrcanche per shell non interattive):

    [[$ - == * i *]] || ritorna 0
    
    PS1 = '\ h \ w \ $'
    
    start () {sudo service "$ 1" start; }
    

Tuttavia, c'è anche il problema che alcuni comandi non interattivi (ad es. ssh <host> ls) Saltano ~/.profile, ma le variabili d'ambiente sarebbero molto utili per loro.

  • Alcune distribuzioni (ad es. Debian) compilano il loro bash con l'opzione di sorgente ~/.bashrcper tali accessi non interattivi. In questo caso, ho trovato utile spostare tutte le variabili di ambiente (le export ...linee) in un file separato ~/.environ, e di origine da entrambi .profile e .bashrc, con una guardia per evitare di farlo due volte:

    Se ! ["$ PREFIX"]; poi    # o $ EDITOR, o $ TZ, o ... 
        . ~ / .environ            # in genere qualsiasi variabile impostata da .environ stesso
    fi
    
  • Sfortunatamente, per altre distribuzioni (ad esempio Arch), non ho trovato un'ottima soluzione. Una possibilità è quella di utilizzare il modulo PAM pam_env (abilitato per impostazione predefinita) inserendo quanto segue ~/.pam_environment:

    BASH_ENV =. /. Environment         # non un errore di battitura; deve essere un percorso, ma ~ non funzionerà
    

    Quindi, ovviamente, l'aggiornamento ~/.environa unset BASH_ENV.


Conclusione? Le conchiglie sono un dolore. Le variabili d'ambiente sono un dolore. Le opzioni di tempo di compilazione specifiche per la distribuzione sono un dolore immenso nel culo.


2
+1 per l'ultimo paragrafo, ma preferisco di sourcing .profilee .bashrcda .bash_profilee mantenere .profilepulito.
nyuszika7h

@ nyuszika7h: la mia .profile è pulita , grazie.
Grawity,

1
Nota il commento ogni volta che apri una finestra è il contrario per OSX
Segna il

1
"Non ha molto senso avere entrambi ~/.profilee ~/.bash_profile": non sono d'accordo. Vedi la risposta di Dan per il perché.
rubenvb,

@rubenvb Puoi citare la parte rilevante? Penso che sia giusto avere solo un .profilee proteggere le bashparti specifiche con i condizionali.
Kelvin

36

Dai un'occhiata a questo eccellente post sul blog di ShreevatsaR . Ecco un estratto, ma vai al post del blog, include una spiegazione per termini come "login shell", un diagramma di flusso e una tabella simile per Zsh.

Per Bash, funzionano come segue. Leggi la colonna appropriata. Esegue A, quindi B, quindi C, ecc. B1, B2, B3 significa che esegue solo il primo di quei file trovati.

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+

Questo è carino. È importante notare che di solito /etc/profilechiama /etc/bash.bashrce ~/.profilechiama ~.bashrc. In modo efficace /etc/bash.bashrce ~/.bashrcvengono eseguiti anche per accessi interattivi.
Wisbucky,

Nota che alcune distribuzioni sembrano prevalere su questo schema (con strane conseguenze) - vedi ad esempio il mio rapporto sui bug da aprire qui: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz

Btw. almeno con bash nessuno di questi file viene eseguito quando il bash viene chiamato tramite/bin/sh
JepZ

@JepZ Hai ragione, ecco cosa spiega la terza colonna "Script".
Flimm,

1
@Flimm Bene, la colonna 'Script' descrive cosa succede quando si avvia uno script non interattivo tramite bash (ad es. / Bin / bash). Tuttavia, se si avvia uno script tramite sh (e / bin / sh è un collegamento simbolico a / bin / bash) nessuno dei precedenti viene eseguito (nemmeno BASH_ENV). Il relativo paragrafo della pagina man di bash può essere trovato cercando If bash is invoked with the name sh.
JepZ

21

Ti offro le mie linee guida "complete":

  • Crea .bash_profilee .profilecarica .bashrcse esiste, usando ad es [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Inserisci tutto il resto .bashrc.
  • Smettila di preoccuparti.
  • Ogni quattro anni circa, dedica dieci minuti alla ricerca di questa domanda prima di arrendersi e tornare a "non preoccuparsi".

EDIT: Aggiunte le citazioni di paura a "complete" nel caso in cui qualcuno è tentato di crederci. ;)


3
Avere entrambi .bash_profileed .profileè un po 'ridondante; hai solo bisogno di quest'ultimo. È necessario renderlo / bin / sh-proof, tuttavia: if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fipoiché esistono programmi (ovvero gdm / lightdm) che generano manualmente il file da uno script / bin / sh. Ciò significa anche che l'ambiente conservato .bashrcsarebbe inefficace. Ho dovuto -1, poiché le linee guida "complete" non funzioneranno su molti sistemi, come avevo scoperto molte volte nel modo più duro.
Grawity,

Nessun problema, pagherei felicemente un -1 per una risposta che non è semplicemente "comprensiva", e sicuramente ti sei guadagnato quel titolo.
Pesce meccanico,

0

Ho rinunciato a cercare di capirlo e ~/.shell-setupho creato una sceneggiatura ( ) che provengo da tutte le altre.

Questo approccio richiede ~/.shell-setupdue funzionalità:

  1. Esegui una sola volta, anche se proveniente ripetutamente (usa Includi protezioni )
  2. Non generare alcun output indesiderato (rileva quando l'output è ok)

Il numero 1 è piuttosto standard, anche se forse non è molto usato negli script di shell.

# 2 è più complicato. Ecco cosa uso in bash:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

Sfortunatamente non ricordo come mi sia venuto in mente, o perché non fosse sufficiente rilevare una shell interattiva .


-2

Mettere tutto in .bashrce quindi fonte .bashrcdi.profile

Dalla pagina man di bash (su OS X 10.9):

Quando viene avviata una shell interattiva che non è una shell di accesso, bash legge ed esegue i comandi da ~ / .bashrc, se quel file esiste. Questo può essere inibito usando l'opzione --norc. L'opzione --rcfile forzerà bash a leggere ed eseguire comandi da file anziché ~ / .bashrc

Il testo sopra è il motivo per cui tutto viene inserito .bashrc. Tuttavia, c'è un comportamento leggermente diverso quando si ha a che fare con una shell di accesso. Ancora una volta, citando dalla pagina man:

Quando bash viene invocato come shell di login interattiva o come shell non interattiva con l'opzione --login, legge prima ed esegue i comandi dal file / etc / profile, se quel file esiste. Dopo aver letto quel file, cerca ~ / .bash_profile, ~ / .bash_login e ~ / .profile, in quell'ordine, e legge ed esegue i comandi dal primo che esiste ed è leggibile. L'opzione --noprofile può essere usata all'avvio della shell per inibire questo comportamento.

.profileviene letto per le shell di accesso, ma .bashrcnon lo è. Duplicare tutte queste cose in .bashrcè male ™, quindi dobbiamo procurarle .profilein modo che il comportamento rimanga coerente.

Tuttavia, non si desidera ottenere .bashrcda .profileincondizionatamente. Si prega di consultare i commenti e altre risposte per ulteriori dettagli.


4
-1, NON fonte .bashrcda .profile. Vedi la risposta di @ DanRabinowitz.
nyuszika7h

Almeno non incondizionatamente.
nyuszika7h

[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcsarebbe un dolce oneliner per .profile.
John WH Smith,

@ nyuszika7h, perché no? Tutti sembrano suggerire di farlo.
Pacerier,
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.