Escolhendo entre .bashrc, .profile, .bash_profile, etc [duplicado]

197

Esta pergunta já tem uma resposta aqui:

Isso é constrangedor, mas depois de muitos anos de utilização de sistemas POSIX em tempo integral, eu ainda tenho um tempo difícil descobrir se uma personalização shell deve ir .bashrc, .profileou em outro lugar. Sem mencionar alguns dos arquivos de configuração específicos do SO, como .pam_environment.

Sim, eu sei como resolver a documentação e aprender quando cada arquivo é ou não é carregado. O que me pergunto é se alguém tem todas as diretrizes completas para decidir em qual arquivo colocar um determinado tipo de personalização.

Avdi
fonte
6
esta pergunta não deve ser marcada como duplicada, porque o .profile não está disponível na pergunta adicionada.
Premraj
Resposta

Respostas:

222

TL; DR:

  • ~/.bash_profiledeve ser super simples e apenas carregar .profilee .bashrc(nessa ordem)

  • ~/.profiletem o material NÃO especificamente relacionado ao bash, como variáveis ​​de ambiente ( PATHe amigos)

  • ~/.bashrctem o que você deseja em uma linha de comando interativa. Prompt de comando, EDITORvariável, aliases de bash para meu uso

Algumas outras notas:

  • Qualquer coisa que deva estar disponível para aplicações gráficas OU para sh (ou bash invocado como sh) DEVE estar dentro~/.profile

  • ~/.bashrc não deve produzir nada

  • Qualquer coisa que deva estar disponível apenas para os shells de login deve entrar ~/.profile

  • Verifique se isso ~/.bash_loginnão existe.

Dan Rabinowitz
fonte
3
+1, isso permite ~/.profiledefinir corretamente o ambiente para serviços como GDM / LightDM / LXDM que executam explicitamente / bin / sh.
grawity
12
Minhas .bashrcsaídas muitas coisas, você pode comentar sobre isso? Em particular, onde devo colocar a saída de saudação?
Calimo 29/07
14
@Calimo: Crie apenas itens de saída no modo interativo. Você pode testá-lo usando [[ $- == *i* ]], ou seja, procurando 'i' na $-variável especial . Obviamente, isso só importa em primeiro lugar nos sistemas em que o bash é compilado para ser lido .bashrcno modo não interativo. (Ou seja, o Debian, mas não o Arch.) Mas é uma causa frequente de mensagens de erro misteriosas ao tentar conectar-se usando sftpou scpferramentas semelhantes.
grawity
4
Agora eu tenho que saber - por que o .bash_login não deveria existir? O que isso faz?
tedder42
11
@ tedder42: Faz o mesmo que .bash_profilee .profile. Mas o bash lê apenas o primeiro de três. Significado, se você tiver um .bash_login, então ambos .profilee .bash_profileserão misteriosamente ignorados.
grawity
54

Ao longo dos últimos anos, eu tinha um monte de tempo a perder, então eu ter pesquisado isso por um pouco mais de apenas 10 minutos. Não tenho idéia se esse é o melhor layout, é apenas aquele que funciona corretamente em praticamente todos os casos.

Os requisitos:

  • ~/.profile deve ser compatível com qualquer / bin / sh - isso inclui bash, dash, ksh, qualquer outra coisa que uma distribuição possa optar por usar.

  • As variáveis ​​de ambiente devem ser colocadas em um arquivo que seja lido pelos logins do console (por exemplo, um shell de 'login') e pelos logons gráficos (por exemplo, gerenciadores de exibição como GDM, LightDM ou LXDM).

  • Há muito pouco sentido em ter ambos ~/.profile e ~/.bash_profile. Se o último estiver faltando, o bash usará o primeiro com prazer, e qualquer linha específica do bash poderá ser protegida com uma verificação de $BASHou $BASH_VERSION.

  • A separação entre *profilee *rcé que o primeiro é usado para shells de 'login' e o segundo toda vez que você abre uma janela do terminal. No entanto, o bash no modo 'login' não é originado ~/.bashrc, portanto, é ~/.profilenecessário fazê-lo manualmente.

A configuração mais simples seria:

  • Tenha um ~/.profileque defina todas as variáveis ​​de ambiente (exceto as específicas do bash), talvez imprima uma linha ou duas e depois as fontes, ~/.bashrcse estiver sendo executado pelo bash, seguindo a sintaxe compatível com sh.

    exportar TZ = "Europa / Paris"
    exportar EDITOR = "vim"
    if ["$ BASH"]; então
        . ~ / .bashrc
    fi
    tempo de atividade
    
  • Tenha uma ~/.bashrcque execute qualquer configuração específica do shell, protegida com uma verificação do modo interativo para evitar quebras de coisas como sftpno Debian (onde o bash é compilado com a opção de carregar ~/.bashrcmesmo para shells não interativos):

    [[$ - == * i *]] || retornar 0
    
    PS1 = '\ h \ w \ $'
    
    start () {serviço sudo "$ 1" start; }
    

No entanto, também há o problema de que certos comandos não interativos (por exemplo ssh <host> ls) pulam ~/.profile, mas as variáveis ​​de ambiente seriam muito úteis para eles.

  • Certas distribuições (por exemplo, Debian) compilam seu bash com a opção de ~/.bashrcobter esses logins não interativos. Nesse caso, achei útil mover todas as variáveis ​​de ambiente (as export ...linhas) para um arquivo separado ~/.environe obtê-lo de ambos .profile e .bashrc, com um protetor, para evitar fazer isso duas vezes:

    E se ! ["$ PREFIX"]; em seguida,    # ou $ EDITOR, ou US $ TZ, ou ... 
        . ~ / .environ            # geralmente qualquer variável que o próprio .environ defina
    fi
    
  • Infelizmente, para outras distribuições (por exemplo, Arch), não encontrei uma solução muito boa. Uma possibilidade é usar o módulo PAM (ativado por padrão) pam_env, colocando o seguinte em ~/.pam_environment:

    BASH_ENV =. /. Environment         # não é um erro de digitação; precisa ser um caminho, mas ~ não vai funcionar
    

    Então, é claro, atualizando ~/.environpara unset BASH_ENV.


Conclusão? Conchas são uma dor. Variáveis ​​de ambiente são uma dor. As opções de tempo de compilação específicas da distribuição são um imenso problema .

gravidade
fonte
2
+1 para o último parágrafo, mas eu prefiro fornecimento .profilee .bashrcde .bash_profilee manter .profilelimpo.
nyuszika7h
@ nyuszika7h: Meu .profile está limpo , obrigado.
grawity
11
Observe o comentário re cada vez que você abrir uma janela é o contrário para OSX
Mark
11
"Há muito pouco sentido em ter os dois ~/.profilee ~/.bash_profile": eu discordo. Veja a resposta de Dan para o porquê.
31414 Rubenvb
@rubenvb Você pode citar a parte relevante? Eu acho que é bom ter apenas um .profilee guardar as bashpartes específicas com condicionais.
Kelvin3 /
36

Dê uma olhada neste excelente post de ShreevatsaR . Aqui está um extrato, mas acesse a postagem do blog, que inclui uma explicação para termos como "shell de login", um fluxograma e uma tabela semelhante para o Zsh.

Para o Bash, eles funcionam da seguinte maneira. Leia a coluna apropriada. Executa A, depois B, C, etc. O B1, B2, B3 significa que ele executa apenas o primeiro desses arquivos encontrados.

+----------------+-----------+-----------+------+
|                |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      |           |      |
+----------------+-----------+-----------+------+
Flimm
fonte
Isso é legal. É importante observar que geralmente /etc/profilechamadas /etc/bash.bashrce ~/.profilechamadas ~.bashrc. Tão eficazmente /etc/bash.bashrce também ~/.bashrcestão sendo executados para logins interativos.
wisbucky
Note-se que algumas distribuições parecem substituir esse esquema (com consequências estranhas) - ver, por exemplo minha bugreport para openSUSE aqui: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz
Btw. pelo menos com o bash, nenhum desses arquivos está sendo executado quando o bash está sendo chamado via/bin/sh
JepZ
@JepZ Você está certo, é o que a terceira coluna "Script" explica.
Flimm
11
Bem, a coluna 'Script' descreve o que acontece quando você inicia um script não interativo via bash (por exemplo, / bin / bash). No entanto, se você iniciar um script via sh (e / bin / sh for um link simbólico para / bin / bash), nenhuma das opções acima será executada (nem mesmo BASH_ENV). O parágrafo relacionado da página de manual do bash pode ser encontrado pesquisando If bash is invoked with the name sh.
JepZ 9/04
21

Ofereço minhas diretrizes "abrangentes":

  • Faça .bash_profilee .profilecarregue, .bashrcse existir, usando, por exemplo [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • Coloque todo o resto .bashrc.
  • Pare de se preocupar.
  • A cada quatro anos, gaste dez minutos pesquisando essa questão antes de desistir e voltar a "não se preocupar".

EDIT: Adicionado citações de medo para "abrangente", caso alguém se sinta tentado a acreditar. ;)

Peixe Mecânico
fonte
3
Ter os dois .bash_profilee .profileé um pouco redundante; você só precisa do último. Você precisa torná-lo / bin / sh-proof, no entanto if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fi:, pois existem programas (nomeadamente gdm / lightdm) que originam manualmente o arquivo a partir de um script / bin / sh. Isso também significa que o ambiente mantido .bashrcseria ineficaz. Tinha que -1, pois suas diretrizes "abrangentes" não funcionarão em muitos sistemas, como eu havia descoberto da maneira mais difícil várias vezes.
grawity 29/07
Sem problemas, eu ficaria feliz em pagar -1 por uma resposta que não seja meramente "abrangente" e você certamente ganhou esse título.
Mechanical Fish
0

Desisti de tentar descobrir isso e criei um script ( ~/.shell-setup), que sou fonte de todos os outros.

Essa abordagem requer ~/.shell-setupdois recursos:

  1. Execute apenas uma vez, mesmo quando originado repetidamente (use Guardas de inclusão )
  2. Não gere nenhuma saída indesejada (detecte quando a saída está correta)

# 1 é bastante padrão, embora talvez não seja muito usado em scripts de shell.

# 2 é mais complicado. Aqui está o que eu uso no bash:

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

Infelizmente, não me lembro de como surgiu isso, ou por que detectar um shell interativo não era suficiente.

ShadSterling
fonte
-2

Coloque tudo em .bashrce, em seguida, fonte .bashrcde.profile

Na página do man bash (no OS X 10.9):

Quando um shell interativo que não é um shell de login é iniciado, o bash lê e executa comandos de ~ / .bashrc, se esse arquivo existir. Isso pode ser inibido usando a opção --norc. A opção --rcfile file forçará o bash a ler e executar comandos do arquivo em vez de ~ / .bashrc

O texto acima é o motivo pelo qual tudo é colocado .bashrc. No entanto, há um comportamento um pouco diferente ao lidar com um shell de login. Novamente, citando a partir da página de manual:

Quando o bash é chamado como um shell de login interativo ou como um shell não interativo com a opção --login, ele primeiro lê e executa comandos do arquivo / etc / profile, se esse arquivo existir. Depois de ler esse arquivo, ele procura ~ / .bash_profile, ~ / .bash_login e ~ / .profile, nessa ordem, e lê e executa comandos do primeiro que existe e é legível. A opção --noprofile pode ser usada quando o shell é iniciado para inibir esse comportamento.

.profileé lido para shells de login, mas .bashrcnão é. Duplicar tudo isso .bashrcé ruim ™, por isso precisamos fornecê-lo .profilepara que o comportamento permaneça consistente.

No entanto, você não deseja obter .bashrcde forma .profileincondicional. Consulte os comentários e outras respostas para obter detalhes adicionais.

mat-
fonte
4
-1, NÃO fonte .bashrcde .profile. Veja a resposta de @ DanRabinowitz.
nyuszika7h
Pelo menos não incondicionalmente.
nyuszika7h
[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcseria um doce delineador para .profile.
John WH Smith
@ nyuszika7h, por que não? Todo mundo parece sugerir isso.
Pacerier