2010-09-02 14:40:34 +0000 2010-09-02 14:40:34 +0000
453
453

Differenza tra .bashrc e .bash_profile

Qual è la differenza tra .bashrc e .bash_profile e quale dovrei usare?

Risposte (6)

528
528
528
2010-09-02 19:23:14 +0000

Tradizionalmente, quando entrate in un sistema Unix, il sistema avvia un programma per voi. Quel programma è una shell, cioè un programma progettato per avviare altri programmi. È una shell a riga di comando: si avvia un altro programma digitando il suo nome. La shell predefinita, una shell Bourne, legge i comandi da ~/.profile quando viene invocata come shell di login.

Bash è una shell simile a Bourne. Legge i comandi da ~/.bash_profile quando viene invocata come shell di login, e se quel file non esiste¹, prova a leggere invece ~/.profile.

Potete invocare una shell direttamente in qualsiasi momento, per esempio lanciando un emulatore di terminale all'interno di un ambiente GUI. Se la shell non è una shell di login, non legge ~/.profile. Quando si avvia bash come shell interattiva (cioè, non per eseguire uno script), legge ~/.bashrc (tranne quando viene invocata come shell di login, allora legge solo ~/.bash_profile o ~/.profile.

Quindi:

  • ~/.profile è il posto dove mettere le cose che si applicano alla tua intera sessione, come i programmi che vuoi avviare quando entri (ma non i programmi grafici, quelli vanno in un file diverso), e le definizioni delle variabili d'ambiente.

  • ~/.bashrc è il posto dove mettere roba che si applica solo a bash stessa, come definizioni di alias e funzioni, opzioni della shell e impostazioni del prompt. (Potresti anche metterci le associazioni di tasti, ma per bash normalmente vanno in ~/.inputrc).

  • ~/.bash_profile può essere usato al posto di ~/.profile, ma viene letto solo da bash, non da qualsiasi altra shell. (Questo è soprattutto un problema se vuoi che i tuoi file di inizializzazione funzionino su più macchine e la tua shell di login non è bash su tutte). Questo è un posto logico per includere ~/.bashrc se la shell è interattiva. Raccomando i seguenti contenuti in ~/.bash_profile:

Sui moderni dispositivi, c'è un'ulteriore complicazione relativa a ~/.profile. Se fai il login in un ambiente grafico (cioè, se il programma dove digiti la tua password è in esecuzione in modalità grafica), non ottieni automaticamente una shell di login che legge ~/.profile. A seconda del programma di login grafico, del window manager o dell'ambiente desktop che esegui dopo, e di come la tua distribuzione ha configurato questi programmi, il tuo ~/.profile può essere letto o meno. Se non lo è, di solito c'è un altro posto dove puoi definire le variabili d'ambiente e i programmi da lanciare quando entri, ma purtroppo non c'è una posizione standard.

Notate che potreste vedere qua e là raccomandazioni di mettere le definizioni delle variabili d'ambiente in ~/.bashrc o di lanciare sempre le shell di login nei terminali. Entrambe sono cattive idee. Il problema più comune con entrambe queste idee è che le vostre variabili d'ambiente saranno impostate solo nei programmi lanciati 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 ripiegare su .profile. Sentitevi liberi di dimenticare che esiste.

54
54
54
2010-09-02 14:54:04 +0000

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.

Cos'è una shell di login o non-login?

Quando fai il login (es: digiti nome utente e password) via console, sia stando fisicamente seduto sulla macchina all'avvio, sia da remoto via ssh: .bash\profile viene eseguito per configurare le cose prima del prompt dei comandi iniziale.

Ma, se hai già effettuato l'accesso alla tua macchina e apri una nuova finestra di terminale (xterm) dentro Gnome o KDE, allora .bashrc viene eseguito prima del prompt dei comandi della finestra. .bashrc viene anche eseguito quando avvii una nuova istanza di bash digitando /bin/bash in un terminale.

35
35
35
2010-09-02 18:10:20 +0000

Ai vecchi tempi, quando le pseudo tty non erano pseudo e in realtà, beh, si digitava, e gli UNIX erano accessibili da modem così lenti che potevi vedere ogni lettera che veniva stampata sul tuo schermo, l'efficienza era fondamentale. Per aiutare un po’ l'efficienza si aveva il concetto di una finestra principale di accesso e qualsiasi altra finestra si usava per lavorare effettivamente. Nella vostra finestra principale, vorreste le notifiche a qualsiasi nuova posta, possibilmente eseguire alcuni altri programmi in background.

Per supportare tutto ciò, le shell hanno creato un file .profile specificamente su ‘login shell’. Questo farebbe lo speciale, una volta impostata una sessione. Bash ha esteso questo in qualche modo per guardare a .bash_profile prima di .profile, in questo modo si possono mettere solo cose di bash lì dentro (in modo da non rovinare Bourne shell, ecc, che guardano anche a .profile). Le altre shell, non-login, avrebbero solo sorgente il file rc, .bashrc (o .kshrc, ecc.).

Questo è un po’ un anacronismo ora. Non si entra in una shell principale tanto quanto si entra in un gestore di finestre della gui. Non c'è una finestra principale diversa da qualsiasi altra finestra.

Il mio suggerimento - non preoccupatevi di questa differenza, è basata su un vecchio stile di utilizzo di unix. Elimina la differenza nei tuoi file. L'intero contenuto di .bash\profile dovrebbe essere:

[-f $HOME/.bashrc] && . $HOME/.bashrc

E mettete tutto ciò che volete effettivamente impostare in .bashrc

Ricordate che .bashrc è sourced per tutte le shell, interattive e non. Potete cortocircuitare il sourcing per le shell non interattive mettendo questo codice in cima a .bashrc:

[[$- != *i*]] && return

19
19
19
2016-07-13 08:53:44 +0000

Date un'occhiata a questo eccellente post sul blog di ShreevatsaR . Ecco un estratto, ma andate al post sul blog, include una spiegazione di termini come “login shell”, un diagramma di flusso e una tabella simile per Zsh.

Per Bash, funzionano come segue. Leggete la colonna appropriata. Esegue A, poi B, poi C, ecc. Il 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 | | |
+----------------+-----------+-----------+------+
5
5
5
2016-10-18 18:13:24 +0000

UN COMMENTO MIGLIORE PER LA TESTA DI /ETC/PROFILE

Basandomi sulla grande risposta di Flimm qui sopra, ho inserito questo nuovo commento nella testa del mio /etc/profile di Debian, (potrebbe essere necessario adattarlo alla vostra distro.):

# 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 nella testa di ciascuno degli altri file di configurazione per farvi riferimento:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

Degno di nota penso sia il fatto che il /etc/profile di Debian per default sorveglia (include) /etc/bash.bashrc (questo quando esiste /etc/bash.bashrc). Così 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 interattivamente. Quindi questi due file sono solo per gli script interattivi.

4
4
4
2019-06-24 22:55:40 +0000

La logica di configurazione di bash stessa non è follemente complicata e spiegata in altre risposte in questa pagina, su serverfault e in molti blog. Il problema però è quello che le distribuzioni Linux fanno di bash, intendo i complessi e vari modi in cui configurano bash di default. http://mywiki.wooledge.org/DotFiles accenna brevemente ad alcune di queste stranezze. Ecco un esempio di tracciamento su Fedora 29, mostra quali file generano quali altri file e in quale ordine per uno scenario molto semplice: connettersi da remoto con ssh e poi avviare un'altra subshell:

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 che la stessa bash non conosce, cioè non direttamente. Lo /etc/bashrc di Fedora verifica se:

  • viene prelevato da una shell di login,
  • viene prelevato da una shell interattiva,
  • è già stato prelevato

… e poi fa cose completamente diverse a seconda di queste.

Se pensate di poter ricordare il grafico qui sopra, allora peccato perché non è sufficiente: questo grafico descrive semplicemente uno scenario, cose leggermente diverse accadono quando si eseguono script non interattivi o si avvia una sessione grafica. Ho omesso ~/.profile. Ho omesso gli script bash_completion. Per ragioni di compatibilità all'indietro, invocare bash come /bin/sh invece di /bin/bash cambia il suo comportamento. E per quanto riguarda zsh e altre shell? E naturalmente diverse distribuzioni Linux fanno le cose in modo diverso, per esempio Debian e Ubuntu hanno una versione non standard di bash, che ha delle personalizzazioni specifiche per Debian. In particolare cerca un file insolito: /etc/bash.bashrc. Anche se ci si attiene ad una sola distribuzione Linux, probabilmente si evolve nel tempo. Aspetta: non abbiamo nemmeno toccato macOS, FreeBSD,… Infine, facciamo un pensiero agli utenti bloccati dai 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é si vuole solo aggiungere nuovi valori, qualche “prova ed errore” tende ad essere sufficiente. Il vero divertimento inizia quando si vuole modificare in un file (utente) qualcosa già definito in un altro (in /etc). Allora preparatevi a passare un po’ di tempo a progettare una soluzione che non sarà mai portabile.

Per un ultimo po’ di divertimento ecco il “grafico dei sorgenti” 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