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

174

Isso é vergonhoso, mas depois de muitos anos usando sistemas POSIX em tempo integral, ainda tenho dificuldade em descobrir se uma personalização de shell deve ir em .bashrc , .profile ou em outro lugar. Sem mencionar alguns dos arquivos de configuração específicos do sistema operacional, como .pam_environment .

Sim, sei como detalhar a documentação e saber quando cada arquivo é ou não carregado. O que eu estou querendo saber é se alguém tem todas as orientações completas sobre como decidir em qual arquivo colocar um determinado tipo de personalização.

    
por Avdi 29.07.2014 / 05:14

6 respostas

193

TL; DR:

  • ~/.bash_profile deve ser super simples e carregar apenas .profile e .bashrc (nessa ordem)

  • ~/.profile tem as coisas NÃO especificamente relacionados ao bash, como variáveis de ambiente ( PATH e amigos)

  • ~/.bashrc tem tudo o que você deseja em uma linha de comando interativa. Prompt de comando, EDITOR variable, bash aliases para meu uso

Algumas outras notas:

  • Qualquer coisa que deve estar disponível para aplicativos gráficos OU sh (ou bash invocado como sh ) DEVE estar em ~/.profile

  • ~/.bashrc não deve produzir nada

  • Tudo o que deve estar disponível apenas para os shells de login deve ir em ~/.profile

  • Verifique se ~/.bash_login não existe.

por 29.07.2014 / 06:27
46

Nos últimos anos, tive muito tempo a perder, então pesquisei isso por pouco mais de 10 minutos. Não faço ideia se este é o melhor layout, é apenas um que funciona corretamente em praticamente todos os casos.

Os requisitos:

  • ~/.profile deve ser compatível com qualquer / bin / sh - isso inclui bash, dash, ksh, o que mais uma distro escolher usar.

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

  • Não faz muito sentido ter ambos ~/.profile e ~/.bash_profile . Se este último estiver faltando, o bash terá todo o prazer em usar o primeiro, e qualquer linha específica do bash pode ser guardada com uma verificação de $BASH ou $BASH_VERSION .

  • A separação entre *profile e *rc é que o primeiro é usado para shells de 'login' e o último sempre que você abre uma janela de terminal. No entanto, bash no modo 'login' não fornece ~/.bashrc , portanto, ~/.profile precisa fazer isso manualmente.

A configuração mais simples seria:

  • Tenha um ~/.profile que defina todas as variáveis de ambiente (exceto as específicas do bash), talvez imprima uma ou duas linhas, depois fontes ~/.bashrc se estiver sendo executado pelo bash, mantendo a sintaxe compatível com sh.

    export TZ="Europe/Paris"
    export EDITOR="vim"
    if [ "$BASH" ]; then
        . ~/.bashrc
    fi
    uptime
    
  • Tenha um ~/.bashrc que realiza qualquer configuração específica do shell, protegida com uma verificação do modo interativo para evitar problemas como sftp no Debian (onde o bash é compilado com a opção de carregar ~/.bashrc mesmo para shells não interativos):

    [[ $- == *i* ]] || return 0
    
    PS1='\h \w \$ '
    
    start() { sudo service "$1" start; }
    

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

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

    if ! [ "$PREFIX" ]; then   # or $EDITOR, or $TZ, or ...
        . ~/.environ           # generally any variable that .environ itself would set
    fi
    
  • Infelizmente, para outras distribuições (por exemplo, Arch), não encontrei uma solução muito boa. Uma possibilidade é usar o módulo PAM pam_env (ativado por padrão), colocando o seguinte em ~/.pam_environment :

    BASH_ENV=./.environ        # not a typo; it needs to be a path, but ~ won't work
    

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

Conclusão? Conchas são uma dor. Variáveis de ambiente são uma dor. Opções específicas de tempo de compilação de distribuição são um imenso dor no rabo.

    
por 29.07.2014 / 08:52
29

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

For Bash, they work as follows. 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.

+----------------+-----------+-----------+------+
|                |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      |           |      |
+----------------+-----------+-----------+------+
    
por 29.07.2014 / 17:28
19

Eu ofereço minhas diretrizes "abrangentes":

  • Crie .bash_profile e .profile load .bashrc , se existir, usando, por exemplo, %código%
  • Coloque todo o resto em [ -r $HOME/.bashrc ] && source $HOME/.bashrc .
  • Pare de se preocupar.
  • A cada quatro anos, passe dez minutos pesquisando essa mesma pergunta antes de desistir e voltar a "não se preocupar".

EDIT: Adicionado citações assustadoras para "abrangente" apenas no caso de alguém é tentado a acreditar. ;)

    
por 29.07.2014 / 05:39
0

Eu desisti de tentar descobrir isso e fiz um script ( ~/.shell-setup ) que eu utilizei de todos os outros.

Essa abordagem exige que ~/.shell-setup tenha dois recursos:

  1. Execute somente uma vez, mesmo quando originado repetidamente (use Incluir proteções )
  2. Não gere nenhuma saída indesejada (detecte quando a saída estiver ok)

# 1 é bastante normal, 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 descobri isso ou porque detectar um shell interativo não era suficiente .

    
por 31.07.2014 / 04:45
-1

Coloque tudo em .bashrc e, em seguida, escolha .bashrc em .profile

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

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc

O texto acima é o motivo pelo qual tudo é colocado em .bashrc . No entanto, há um comportamento um pouco diferente quando você está lidando com um shell de login. Novamente, citando a página man:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

.profile é lido para os shell de login, mas .bashrc não é. Duplicar todas essas coisas em .bashrc é ruim ™, por isso, precisamos fornecer isso em .profile para que o comportamento permaneça consistente.

No entanto, você não deseja obter .bashrc de .profile incondicionalmente. Por favor, veja os comentários e outras respostas para detalhes adicionais.

    
por 29.07.2014 / 05:50