Qual è la differenza tra .bashrc
e .bash_profile
e quale dovrei usare?
.profile
, dai un'occhiata a questa domanda: superuser.com/questions/789448/…
Qual è la differenza tra .bashrc
e .bash_profile
e quale dovrei usare?
.profile
, dai un'occhiata a questa domanda: superuser.com/questions/789448/…
Risposte:
Tradizionalmente, quando si accede a un sistema Unix, il sistema avvia un programma per te. Quel programma è una shell, cioè un programma progettato per avviare altri programmi. È una shell della riga di comando: si avvia un altro programma digitandone il nome. La shell predefinita, una shell Bourne, legge i comandi da ~/.profile
quando viene invocata come shell di accesso.
Bash è una shell tipo Bourne. Legge i comandi da ~/.bash_profile
quando viene invocato come shell di accesso e se quel file non esiste¹, prova ~/.profile
invece a leggere .
È possibile richiamare una shell direttamente in qualsiasi momento, ad esempio avviando un emulatore di terminale all'interno di un ambiente GUI. Se la shell non è una shell di accesso, non legge ~/.profile
. Quando si avvia bash come shell interattiva (ovvero, per non eseguire uno script), si legge ~/.bashrc
(tranne quando viene invocato come shell di login, quindi legge solo ~/.bash_profile
o ~/.profile
.
Perciò:
~/.profile
è il luogo in cui inserire elementi che si applicano all'intera sessione, ad esempio i programmi che si desidera avviare quando si accede (ma non i programmi grafici, entrano in un file diverso) e le definizioni delle variabili di ambiente.
~/.bashrc
è il posto dove mettere cose che si applicano solo a bash stesso, come alias e definizioni di funzioni, opzioni di shell e impostazioni di prompt. (Potresti anche inserire combinazioni di tasti lì, ma per bash normalmente entrano ~/.inputrc
.)
~/.bash_profile
può essere usato al posto di ~/.profile
, ma viene letto solo da bash, non da qualsiasi altra shell. (Questo è principalmente un problema se vuoi che i tuoi file di inizializzazione funzionino su più macchine e la tua shell di login non bash su tutti loro.) Questo è un posto logico da includere ~/.bashrc
se la shell è interattiva. Raccomando i seguenti contenuti in ~/.bash_profile
:
if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
Sui moderni unice, c'è un'ulteriore complicazione correlata ~/.profile
. Se accedi in un ambiente grafico (ovvero, se il programma in cui digiti la password è in esecuzione in modalità grafica), non otterrai automaticamente una shell di accesso che legge ~/.profile
. A seconda del programma di accesso grafico, del gestore di finestre o dell'ambiente desktop che esegui in seguito e di come la tua distribuzione ha configurato questi programmi, ~/.profile
puoi leggere o meno. In caso contrario, di solito c'è un altro posto in cui è possibile definire variabili di ambiente e programmi da avviare quando si accede, ma purtroppo non esiste una posizione standard.
Nota che puoi vedere qui e là consigli per inserire definizioni delle variabili di ambiente ~/.bashrc
o avviare sempre shell di login nei terminali. Entrambe sono cattive idee. Il problema più comune con una di queste idee è che le variabili di ambiente verranno impostate solo nei programmi avviati tramite il terminale, non nei programmi avviati direttamente con un'icona o un menu o una scorciatoia da tastiera.
¹ Per completezza, su richiesta: se .bash_profile
non esiste, bash prova anche .bash_login
prima di tornare a .profile
. Sentiti libero di dimenticare che esiste.
~/.bash_profile
possibile utilizzare l'~/.profile
~/.bashrc
istruzione anziché , ma è necessario includere anche se la shell è interattiva. è fuorviante in quanto si tratta di problemi ortogonali. Non importa se usi ~/.bash_profile
o ~/.profile
devi includere ~/.bashrc
quello che usi se vuoi che le impostazioni da lì abbiano effetto nella shell di login.
~/.bashrc
ha a che fare con la scelta ~/.bash_profile
invece ~/.profile
che non è vera. Se qualcuno include ~/.bashrc
qualsiasi tipo di script che viene fornito al momento dell'accesso (qui è o ~/.bash_profile
o ~/.profile
) è perché desidera che le impostazioni ~/.bashrc
vengano applicate alla shell di accesso nello stesso modo in cui vengono applicate alla shell non di accesso.
Da questo breve articolo
Secondo la pagina man di bash, .bash_profile viene eseguito per le shell di login, mentre .bashrc viene eseguito per le shell interattive non di login.
Che cos'è una shell di login o non login?
Quando si accede (ad esempio: digitare nome utente e password) tramite console, sia fisicamente seduto sulla macchina all'avvio, sia da remoto tramite ssh: .bash_profile viene eseguito per configurare le cose prima del prompt dei comandi iniziale.
Ma, se hai già effettuato l'accesso al tuo computer e hai aperto una nuova finestra di terminale (xterm) all'interno di Gnome o KDE, allora .bashrc viene eseguito prima del prompt dei comandi della finestra. .bashrc viene eseguito anche quando si avvia una nuova istanza bash digitando / bin / bash in un terminale.
Ai vecchi tempi, quando le pseudo-tty non erano pseudo e in realtà, bene, digitate, e UNIX erano accessibili da modem così lenti da poter vedere ogni lettera stampata sullo schermo, l'efficienza era fondamentale. Per aiutare l'efficienza, in qualche modo avevi il concetto di una finestra di accesso principale e di qualsiasi altra finestra in cui funzionavi effettivamente. Nella finestra principale, desideri ricevere notifiche per qualsiasi nuova posta, possibilmente eseguire alcuni altri programmi in background.
A supporto di ciò, le shell hanno fornito un file .profile
specifico su "shell di accesso". Questo farebbe lo speciale, una volta impostato un programma di sessione. Bash lo ha esteso in qualche modo per guardare .bash_profile prima di .profile, in questo modo potresti mettere solo le cose lì dentro (in modo che non rovinino la shell Bourne, ecc., Che hanno anche guardato .profile). Altre shell, senza login, avrebbero solo il sorgente del file rc, .bashrc (o .kshrc, ecc.).
Questo è un po 'un anacronismo ora. Non accedi a una shell principale tanto quanto accedi a un gestore di finestre GUI. Non esiste una finestra principale diversa da qualsiasi altra finestra.
Il mio consiglio: non preoccuparti di questa differenza, si basa su uno stile più vecchio di utilizzo di unix. Elimina la differenza nei tuoi file. L'intero contenuto di .bash_profile dovrebbe essere:
[ -f $HOME/.bashrc ] && . $HOME/.bashrc
E metti tutto ciò che vuoi effettivamente impostare in .bashrc
Ricorda che .bashrc è di provenienza per tutte le shell, interattivo e non interattivo. È possibile cortocircuitare il sourcing per shell non interattive mettendo questo codice nella parte superiore di .bashrc:
[[ $- != *i* ]] && return
.$HOME/.bashrc
come Rich ha mostrato in precedenza, le impostazioni in .bashrc
saranno disponibili in shell di login, e, quindi, l'ambiente desktop pure. Ad esempio, sul mio sistema Fedora, gnome-session
viene avviato come -$SHELL -c gnome-session
, quindi .profile
viene letto.
.bashrc
in .profile
genere non funziona, perché .profile
può essere eseguito da /bin/sh
e non bash (ad esempio su Ubuntu per un accesso grafico di default), e quella shell potrebbe non essere interattiva (ad esempio per un accesso grafico).
[[ $- != *i* ]] && return
"); Mi piace che alcuni dei miei .bashrc
vengano eseguiti anche per shell non interattive, in particolare per impostare env vars, durante l'emissione ssh hostname {command}
, in modo che i comandi remoti vengano eseguiti correttamente (anche se la shell non è interattiva). Altre impostazioni successive .bashrc
dovrebbero essere ignorate. Di solito cerco TERM = stupido e / o non impostato, quindi eseguo il salvataggio in anticipo.
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 | | |
+----------------+-----------+-----------+------+
[ -z "$PS1" ] && return
? La tabella nella mia risposta sta fornendo l'elenco degli script eseguiti da Bash indipendentemente dal contenuto degli script, se lo script stesso ha la linea [ -z "$PS1" ] && return
, ovviamente ciò avrebbe effetto, ma non penso che dovrebbe significare che dovrei cambiare il tavolo.
UN MEGLIO COMMENTO PER IL CAPO DI / ETC / PROFILE
Basandomi sulla grande risposta di Flimm sopra, ho inserito questo nuovo commento a capo del mio profilo Debian / etc / (potrebbe essere necessario modificarlo per la vostra distribuzione) :
# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found. (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# | | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# | | login | non-login |
# +---------------------------------+-------+-----+------------+
# | | | | |
# | ALL USERS: | | | |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV | | | A | not interactive or login
# | | | | |
# +---------------------------------+-------+-----+------------+
# |/etc/profile | A | | | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc | (A) | A | | Better PS1 + command-not-found
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh| (A) | | |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh | (A) | | | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh | (A) | | |
# +---------------------------------+-------+-----+------------+
# | | | | |
# | A SPECIFIC USER: | | | |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile (bash only) | B1 | | | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bash_login (bash only) | B2 | | | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile (all shells) | B3 | | | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc (bash only) | (B2) | B | | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# | | | | |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout | C | | |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)
E questa nota alla testa di ciascuno degli altri file di installazione per fare riferimento ad esso:
# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE
Vale la pena notare che penso che il profilo / etc / di Debian sia di default (include) /etc/bash.bashrc (quando esiste /etc/bash.bashrc). Quindi gli script di login leggono entrambi i file / etc, mentre il non-login legge solo bash.bashrc.
Da notare anche che /etc/bash.bashrc è impostato per non fare nulla quando non viene eseguito in modo interattivo. Quindi questi due file sono solo per script interattivi.
La logica di configurazione di Bash non è follemente complicata e spiegata in altre risposte in questa pagina, su serverfault e in molti blog. Il problema tuttavia è ciò che le distribuzioni Linux fanno di bash , intendo i modi complessi e vari che configurano bash di default. http://mywiki.wooledge.org/DotFiles menziona brevemente alcune di queste stranezze. Ecco una traccia di esempio su Fedora 29, che mostra quali file originano quali altri file e in quale ordine per uno scenario molto semplice: connettersi in remoto con ssh e quindi avviare un'altra sottoshell:
ssh fedora29
└─ -bash # login shell
├── /etc/profile
| ├─ /etc/profile.d/*.sh
| ├─ /etc/profile.d/sh.local
| └─ /etc/bashrc
├── ~/.bash_profile
| └─ ~/.bashrc
| └─ /etc/bashrc
|
|
└─ $ bash # non-login shell
└─ ~/.bashrc
└─ /etc/bashrc
└─ /etc/profile.d/*.sh
La logica più complessa di Fedora è in /etc/bashrc
. Come visto sopra /etc/bashrc
è un file bash di cui non è a conoscenza, intendo non direttamente. I /etc/bashrc
test di Fedora se:
... e poi fa cose completamente diverse a seconda di quelle.
Se pensi di ricordare il grafico sopra, allora è un peccato perché non è quasi sufficiente: questo grafico descrive semplicemente uno scenario, cose leggermente diverse quando si eseguono script non interattivi o si avvia una sessione grafica. Ho omesso ~/.profile
. Ho omesso gli bash_completion
script. Per motivi di compatibilità con le versioni precedenti, invocare bash come /bin/sh
invece di /bin/bash
modificarne il comportamento. Che dire di zsh e di altre shell? E, naturalmente, diverse distribuzioni Linux fanno le cose diversamente, per esempio Debian e Ubuntu hanno una versione non standard di bas h, ha personalizzazioni specifiche di Debian. Cerca in particolare un file insolito:/etc/bash.bashrc
. Anche se ti attieni a una singola distribuzione Linux, probabilmente si evolve nel tempo. Aspetta: non abbiamo nemmeno toccato macOS, FreeBSD, ... Infine, pensiamo agli utenti bloccati con i modi ancora più creativi in cui i loro amministratori hanno configurato il sistema che devono usare.
Come dimostra il flusso infinito di discussioni su questo argomento, è una causa persa. Finché vuoi solo aggiungere nuovi valori, alcuni "tentativi ed errori" tendono ad essere sufficienti. Il vero divertimento inizia quando si desidera modificare in un file (utente) qualcosa già definito in un altro (in / etc). Quindi preparati a dedicare del tempo a progettare una soluzione che non sarà mai portatile.
Per un ultimo divertimento ecco il "grafico sorgente" per lo stesso semplice scenario su Clear Linux a giugno 2019:
ssh clearlinux
└─ -bash # login shell
├── /usr/share/defaults/etc/profile
| ├─ /usr/share/defaults/etc/profile.d/*
| ├─ /etc/profile.d/*
| └─ /etc/profile
├── ~/.bash_profile
|
|
└─ $ bash # non-login shell
├─ /usr/share/defaults/etc/bash.bashrc
| ├─ /usr/share/defaults/etc/profile
| | ├─ /usr/share/defaults/etc/profile.d/*
| | ├─ /etc/profile.d/*
| | └─ /etc/profile
| └─ /etc/profile
└─ ~/.bashrc