Variáveis ​​de ambiente em bash_profile ou bashrc?

Apr 05 2012

Eu achei esta pergunta [blog]: Diferença entre .bashrc e .bash_profile muito útil, mas depois de ver a resposta mais votada (muito boa por sinal), tenho mais perguntas. Perto do final da resposta mais votada e correta, vejo a declaração da seguinte forma:

Observe que você pode ver aqui e ali recomendações para colocar definições de variáveis ​​de ambiente em ~ / .bashrc ou sempre iniciar shells de login nos terminais. Ambos são ideias ruins.

  1. Por que é uma má ideia (não estou tentando lutar, só quero entender)?

  2. Se eu quiser definir uma variável de ambiente e adicioná-la ao PATH (por exemplo JAVA_HOME), onde seria o melhor lugar para colocar a entrada de exportação? em ~ / .bash_profile ou ~ / .bashrc ?

  3. Se a resposta à pergunta número 2 for ~ / .bash_profile , então tenho mais duas perguntas:

    3.1. O que você colocaria em ~ / .bashrc ? apenas apelidos?

    3.2. Em um shell sem login, acredito que o ~ / .bash_profile não está sendo "escolhido". Se a exportação da entrada JAVA_HOME estivesse em bash_profile, eu seria capaz de executar comandos javac e java ? Ele os encontraria no PATH? É por essa razão que alguns posts e fóruns sugerem configurar JAVA_HOME e similares como ~ / .bashrc ?

    Desde já, obrigado.

Respostas

28 geekosaur Apr 06 2012 at 04:36

Em um sistema moderno, não é especialmente comum encontrar casos em que é importante, mas isso acontece. (Em particular, se você usar as operações da Shell em vimcomo :r !commandou o in-line !<motion>commandformulário.)

O que você colocaria em ~ / .bashrc? apenas apelidos?

Você coloca coisas ~/.bashrcque não seriam herdadas por subshells automaticamente; isso significa aliases e funções, principalmente, embora às vezes você tenha configurações de variáveis ​​que não deseja que sejam visíveis fora do shell (isso é muito raro). Pode-se argumentar que eles deveriam ser exportados de alguma forma, mas várias tentativas experimentais encontraram problemas de compatibilidade ao tentar escondê-los dentro do ambiente e foram abandonados.

Se eu quiser definir uma variável de ambiente e adicioná-la ao PATH (por exemplo JAVA_HOME), onde seria o melhor lugar para colocar a entrada de exportação? em ~ / .bash_profile ou ~ / .bashrc?

Você coloca as configurações do ambiente ~/.bash_profilepara que recebam configurações iniciais sãs. Às vezes, você desejará substituí-los (geralmente, isso é feito por ambientes complexos como Matlab ou Cadence); se você colocar as configurações de ambiente em ~/.bashrc, os shells executados nesses ambientes perderão as personalizações dos ambientes e, como resultado, as coisas podem não funcionar corretamente. Isso também se aplica se você usar um pacote como módulos , virtualenv , rvm , etc. para gerenciar vários ambientes de desenvolvimento; colocar suas configurações ~/.bashrcsignifica que você não pode executar o ambiente desejado de dentro de seu editor, mas em vez disso será forçado a entrar no padrão do sistema.

Em um shell sem login, acredito que o ~ / .bash_profile não está sendo "escolhido".

Isto está correto; você normalmente quer que o shell inicial seja um shell de login e quaisquer shells iniciados sob aquele não sejam shells de login. Se o shell inicial não for um shell de login, você não terá um padrão PATHou várias outras configurações (incluindo seu JAVA_HOMEexemplo).

A maioria dos ambientes de desktop lançados a partir de gerenciadores de tela (ou seja, a grande maioria dos logins gráficos) não configura um ambiente de login para toda a área de trabalho, então você é forçado a executar o shell inicial nos terminais como um shell de login. Isso causa uma série de problemas (notadamente que o PATHe outros disponíveis para programas executados a partir de painéis, por exemplo, não estão configurados corretamente, porque o painel não é um terminal e não foi executado ~/.bash_profile), mas é um compromisso razoável, visto que nem sempre é possível para ser executado de forma saudável ~/.bash_profileno ambiente não interativo no início de uma sessão iniciada por um gerenciador de exibição, dependendo de seu conteúdo. Às vezes, é sugerido colocar as configurações de ambiente em ~/.bashrcvez de configurar um shell de login; como discutido acima, isso funciona, desde que você não precisa substituir esse ambiente, e provoca rupturas ímpares uma vez que você fazer necessidade de fazê-lo.

Recentemente, ajudei a diagnosticar um problema como este no OS X, onde um usuário que tinha colocado as configurações em ~/.bashrcseguida, começou a usar rvme perlbrew viu um comportamento estranho, porque os ambientes configurados pelos dois foram "desfeitos" por ~/.bashrceditores internos e sudo(que no OS X , ao contrário do Linux, propaga o usuário de $HOMEforma que ele ~/.bashrcseja executado pelo shell do root). Antes de tentar usar esses ambientes, não havia problema; ao começar a usá-los, ficaram perplexos com a perda inesperada de suas configurações.

2 bubu Apr 06 2012 at 04:28

para ser honesto, há pouca diferença hoje em dia, apesar do que o guru tinha a dizer.

o problema por trás disso é que hoje em dia fazemos login graficamente, em vez de por meio de um shell de login. no passado, os usuários do Unix gostavam de ver um breve relatório do que está acontecendo em um servidor imediatamente após o login - então iniciaremos o X pela linha de comando - esses relatórios geralmente requerem algum tempo para serem gerados (por exemplo, 10-20 segundos). e então não queremos ver o mesmo quando iniciamos, por exemplo, xterm. daí a diferença.

hoje em dia não acho que a distinção seja importante agora. Acho que hoje em dia, se você usar o bashrc no bash_profile, ninguém poderá culpar você.

note que isso não se aplica a macos x (cada terminal.app iniciado é um shell de login)

1 hute37 Nov 20 2015 at 10:14

Bem, sobre "Logins gráficos", depende de qual * DM você usa ...

Com GDM (Gnome 3.18) eu tenho este:

/ 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"

Portanto, ~ / .profile é originado no login usando / bin / sh e não / bin / bash

Existem dois casos

  1. / bin / sh está vinculado a / bin / bash, mas é executado no modo "POSIX / Bourne"
  2. / bin / sh é / bin / dash (debian / ubuntu). Mais rápido, mas com menos recursos (suporte ShellShock;) )

Portanto, o perfil / bin / sh é ~ / .profile e não ~ / .bash_profile, ~ / .zprofile

Este arquivo deve ser usado para configurações "agnósticas de shell" , como variáveis ​​de caminho e ambiente.

NENHUM programa executável para interação do usuário somente com login deve estar aqui (verificação de correio, fortuna, etc ...)

os ~ /.* rc destinam-se apenas a sessões "interativas" (apelidos, por exemplo ...)

Há uma diferença entre bash e zsh para shells de login interativos

fontes bash apenas .bash_profile, enquanto fontes zsh na ordem:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / zlogin (aqui os aliases definidos em ~ / .zshrc estão disponíveis. no caso de shells "interativo" + "login"

A maneira certa de fazer ~ / .bash_profile foi respondida aqui:

Diferença entre .bashrc e .bash_profile

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

Para habilitar o teste (e criação de perfil), você pode usar este

~ / .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`
# ------------------------------------------------

então, para testar:

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

Portanto, RVM / virtualenv deve ir em ~ / .profile, IMHO

Mas isso NÃO FUNCIONA , às vezes ...

Por exemplo, virualenvwrapper funciona apenas se o shell que executa o Xsession for um bash "original" (exportando BASH_VERSION)

Se você estiver em um sistema de painel , a variável de ambiente e a configuração do caminho funcionam, mas a definição da função virualenvwrapper não funciona porque o script não é compatível com POSIX.

O script não dá nenhum erro, mas termina sem qualquer definição "workon" .

Portanto, você pode definir o ambiente em ~ / .profile , apenas para habilitar a execução correta do Python do cliente iniciado diretamente do 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

Mas para virualenvwrapper você tem duas alternativas:

  1. fonte-o em ~ / .bash_profile ou ~ / .zprofile (ou ~ / .zlogin) quando o terminal atua como shell de login
  2. inclua o script em ~ / .bashrc ou ~ / zshrc

Isso significa que os clientes X (emacs por exemplo) devem ser iniciados a partir do shell do terminal e não a partir do gráfico!

"Eu não consigo nenhuma satisfação ..."