Variabili d'ambiente in bash_profile o bashrc?


36

Ho trovato questa domanda [blog]: la differenza tra .bashrc e .bash_profile è molto utile ma dopo aver visto la risposta più votata (molto buona tra l'altro) ho ulteriori domande. Verso la fine della risposta più votata e corretta, vedo la dichiarazione come segue:

Si noti che è possibile che vengano visualizzati consigli qua e là per inserire le definizioni delle variabili di ambiente in ~ / .bashrc o avviare sempre shell di accesso nei terminali. Entrambe sono cattive idee.

  1. Perché è una cattiva idea (non sto cercando di combattere, voglio solo capire)?

  2. Se voglio impostare una variabile d'ambiente e aggiungerla al PERCORSO (ad esempio JAVA_HOME) dove sarebbe il posto migliore dove inserire la voce di esportazione? in ~ / .bash_profile o ~ / .bashrc ?

  3. Se la risposta alla domanda numero 2 è ~ / .bash_profile , allora ho altre due domande:

    3.1. Cosa metteresti sotto ~ / .bashrc ? solo alias?

    3.2. In una shell senza login, credo che il ~ / .bash_profile non venga "raccolto". Se l'esportazione della voce JAVA_HOME fosse in bash_profile sarei in grado di eseguire i comandi javac e java ? Li troverebbe sul PERCORSO? È questo il motivo per cui alcuni post e forum suggeriscono di impostare JAVA_HOME e allo stesso modo su ~ / .bashrc ?

    Grazie in anticipo.

Risposte:


26

Su un sistema moderno non è particolarmente comune imbattersi nei casi in cui è importante, ma succede. (In particolare, se si utilizza operazioni shell nei vimquali :r !commando in-linea !<motion>commandforma.)

Cosa metteresti sotto ~ / .bashrc? solo alias?

Inserite cose ~/.bashrcche non sarebbero ereditate automaticamente dai subshells; questo significa alias e funzioni, soprattutto, anche se a volte hai impostazioni variabili che non vuoi siano visibili al di fuori della shell (questo è molto raro). Si potrebbe sostenere che quelli dovrebbero essere esportati in qualche modo, ma vari tentativi sperimentali hanno incontrato problemi di compatibilità con il tentativo di nasconderli all'interno dell'ambiente e sono stati per lo più abbandonati.

Se voglio impostare una variabile d'ambiente e aggiungerla al PERCORSO (ad esempio JAVA_HOME) dove sarebbe il posto migliore dove inserire la voce di esportazione? in ~ / .bash_profile o ~ / .bashrc?

Inserisci le impostazioni dell'ambiente in ~/.bash_profilemodo che vengano fornite impostazioni iniziali sane. A volte vorrai sovrascriverli (spesso questo è fatto da ambienti complessi come Matlab o Cadence); se si inseriscono le impostazioni dell'ambiente, le ~/.bashrcshell eseguite all'interno di tali ambienti perderanno le personalizzazioni degli ambienti e, di conseguenza, le cose potrebbero non funzionare correttamente. Ciò vale anche se si utilizza un pacchetto come moduli , virtualenv , rvm , ecc. Per gestire più ambienti di sviluppo; inserendo le impostazioni ~/.bashrcsignifica che non è possibile eseguire l'ambiente desiderato all'interno dell'editor, ma sarà invece forzato al valore predefinito di sistema.

In una shell senza login, credo che il ~ / .bash_profile non venga "raccolto".

Questo è corretto; normalmente si desidera che la shell iniziale sia una shell di accesso e tutte le shell avviate al di sotto di quella non siano shell di accesso. Se la shell iniziale non è una shell di accesso, non avrai impostazioni predefinite PATHo varie altre (incluso il tuo JAVA_HOMEesempio).

La maggior parte degli ambienti desktop lanciati dai gestori di display (vale a dire, la stragrande maggioranza degli accessi grafici) non imposta un ambiente di accesso per l'intero desktop, quindi si è costretti a eseguire la shell iniziale nei terminali come shell di accesso. Ciò causa una serie di problemi (in particolare il fatto che PATHe quelli disponibili per i programmi eseguiti da, ad esempio, i pannelli non siano impostati correttamente, poiché il pannello non è un terminale e non è stato eseguito ~/.bash_profile), ma è un ragionevole compromesso dato che non è sempre possibile eseguire ~/.bash_profilein modo sicuro in un ambiente non interattivo all'inizio di una sessione avviata da un display manager, a seconda del suo contenuto. A volte viene suggerito di inserire le impostazioni dell'ambiente~/.bashrcinvece di configurare una shell di login; come discusso in precedenza, questo funziona fino a quando non è necessario eseguire l'override quell'ambiente, e le cause rotture dispari una volta che si fa necessità di farlo.

Di recente ho aiutato a diagnosticare un problema come questo su OS X in cui un utente che aveva inserito le impostazioni in ~/.bashrcseguito ha iniziato a utilizzare rvme perlbrew ha visto un comportamento strano, perché gli ambienti impostati dai due erano "annullati" dagli ~/.bashrceditor interni e sudo(che su OS X , a differenza di Linux, propaga l'utente in $HOMEmodo che ~/.bashrcsia gestito dalla shell di root). Prima di provare a usare quegli ambienti, non c'erano problemi; iniziando a usarli, furono sconcertati dalla perdita inaspettata delle loro impostazioni.


1
Penso di aver capito, potrei doverlo leggere più volte per interiorizzarlo di più, ma sto concludendo quanto segue. Negli ambienti aziendali al fine di avere un controllo più preciso delle shell personalizzate senza effetti collaterali di quello globale, è consigliabile mettere le variabili di ambiente in ~ / .bash_profile . In un ambiente personale come Ubuntu o Linux Mint per impostare correttamente il PERCORSO, dovrei impostarlo su ~ / .bashrc (o anche in / etc / profile ). Ho ragione?
Viriato,

Ha meno a che fare con gli ambienti aziendali rispetto al fatto che tu sia solo un utente o uno sviluppatore; i sistemi gradiscono modulese rvmsono strumenti di sviluppo, così come Matlab e Cadence per definizioni leggermente diverse di "sviluppatore". Di sviluppo semplice, inoltre, non richiede loro, ma quando è necessario testare contro più versioni di Ruby, Perl, Python o poi si vuole veramente qualcosa di simile rvm, perlbrewe virtualenv(rispettivamente) in giro per aiutare a mantenere tutto dritto.
Geekosaur,

2

ad essere onesti, in questi giorni c'è poca differenza nonostante ciò che il guru aveva da dire.

il problema è che al giorno d'oggi eseguiamo l'accesso graficamente anziché tramite una shell di accesso. in passato, unix agli utenti piace vedere un breve report di ciò che sta succedendo su un server subito dopo il login - quindi avvieremo X dalla riga di comando - questo report richiede spesso del tempo per essere generato (ad esempio 10-20 secondi). e quindi non vogliamo vedere lo stesso quando iniziamo ad esempio xterm. quindi la differenza.

al giorno d'oggi non penso che la distinzione sia importante adesso. penso che oggigiorno se si procede a bashrc in bash_profile nessuno potrebbe biasimarti.

nota che questo non si applica a macos x (ogni terminal.app avviato è una shell di login)


Non sono esattamente sicuro di aver compreso appieno, ma al lavoro quando eseguo l'accesso tramite ssh che è una shell di accesso, bash_profile e bashrc vengono acquistati, quindi immagino che in quel caso non abbia importanza. Ma se accedo graficamente (cosa significa)? come accedere al mio ubuntu personale?
Viriato,

Concordo con la risposta di @bubu qui: qualsiasi impostazione in cui l' ~/.bash_profileorigine non ~/.bashrcè piuttosto difficile da lavorare e rasenta. Le app grafiche per terminali significano che è più semplice semplicemente source ~ / .bashrc e inserire tutte le configurazioni.
RichVel

1

Bene, su "Login grafici", dipende da quale * DM usi ...

Con GDM (Gnome 3.18) ho questo:

/ Etc / gdm / Xsession

#!/bin/sh   <= *important*

...

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Quindi, ~ / .profile viene fornito in login usando / bin / sh e non / bin / bash

Ci sono due casi

  1. / bin / sh è collegato a / bin / bash ma funziona in modalità "POSIX / Bourne"
  2. / bin / sh è / bin / dash (debian / ubuntu). Il più veloce ma con meno funzioni (supporto ShellShock;) )

Quindi il profilo / bin / sh è ~ / .profile e non ~ / .bash_profile, ~ / .zprofile

Questo file deve essere utilizzato per le impostazioni "shell agnostic" , come le variabili path e environment.

NESSUN programma eseguibile per l'interazione dell'utente di solo accesso dovrebbe essere, ma qui (controllo della posta, fortuna, ecc ...)

~ /.* rc sono pensati solo per sessioni "interattive" (alias per esempio ...)

C'è una differenza tra bash e zsh per le shell di login interattive

bash fonti solo .bash_profile, mentre zsh fa fonti nell'ordine:

  1. ~ / .Zprofile
  2. ~ / .Zshrc
  3. ~ / zlogin (qui sono disponibili alias definiti in ~ / .zshrc. in caso di shell "interattivo" + "login"

Il modo giusto di fare ~ / .bash_profile è stato risposto qui:

Differenza tra .bashrc e .bash_profile

if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

Per abilitare il test (e la profilazione), è possibile utilizzare questo

~ / .Bash_profile:

#!/bin/bash

# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

~ / .Zprofile:

#!/bin/zsh

# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

# no need to source, zsh already handle ~/.zshrc

###case "$-" in *i*) if [ -r ~/.zshrc ]; then . ~/.zshrc; fi;; esac

# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

quindi, per testare:

chsh -s /bin/bash

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env


chsh -s /bin/zsh

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env

Quindi RVM / virtualenv dovrebbe andare in ~ / .profile, IMHO

Ma questo NON FUNZIONA , a volte ...

Ad esempio, virualenvwrapper funziona solo se la shell che esegue Xsession è una bash "originale" (esportando BASH_VERSION)

Se si utilizza un sistema dash , la variabile di ambiente e l'impostazione del percorso funzionano, ma la definizione della funzione virualenvwrapper non funziona perché lo script non è conforme a POSIX.

Lo script non fornisce alcun errore ma termina senza alcuna definizione "workon" .

Quindi puoi impostare l'ambiente a portata di mano in ~ / .profile , solo per abilitare la corretta esecuzione di Python dal client avviato direttamente da X:

export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME

https://gist.github.com/datagrok/2199506

https://www.bountysource.com/issues/9061991-setting-up-your-computer-virtualenvwrapper-linux-all

Ma per virualenvwrapper hai due alternative:

  1. sorgente in ~ / .bash_profile o ~ / .zprofile (o ~ / .zlogin) quando il terminale funge da shell di login
  2. includere lo script in ~ / .bashrc o ~ / zshrc

Questo significa che i client X (ad esempio emacs) dovrebbero essere avviati dalla shell del terminale e non da quella grafica!

"Non posso ottenere nessuna soddisfazione ..."


Una storia completamente diversa sta eseguendo servizi con systemd Alcune possibili alternative sono: scrivere uno script wrapper , definire l'ambiente nel file di definizione "servizio" , scaricare l'ambiente in un file "env" da reperire in una shell padre. Le cose diventano più complicate con RVM / virtualenv ...
hute37
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.