Questão Diferença entre .bashrc e .bash_profile


Qual é a diferença entre .bashrc e .bash_profile e qual devo usar?


401


origem


Veja também esta pergunta semelhante em ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile - Stefan Lasiewski
Se você quer uma explicação mais completa que também envolva .profile, dê uma olhada nesta questão: superuser.com/questions/789448/… - Flimm
Esta resposta também cobre alguns aspectos stackoverflow.com/questions/415403/… - Sergey Voronezhskiy


Respostas:


Tradicionalmente, quando você entra em um sistema Unix, o sistema inicia um programa para você. Esse programa é um shell, ou seja, um programa projetado para iniciar outros programas. É um shell de linha de comando: você inicia outro programa digitando seu nome. O shell padrão, um shell Bourne, lê comandos de ~/.profile quando é invocado como o shell de login.

Bash é uma concha parecida com Bourne. Ele lê comandos de ~/.bash_profile quando é invocado como shell de login, e se esse arquivo não existir, ele tenta ler ~/.profile em vez de.

Você pode invocar um shell diretamente a qualquer momento, por exemplo, iniciando um emulador de terminal dentro de um ambiente de GUI. Se o shell não é um shell de login, ele não lê ~/.profile. Quando você inicia o bash como um shell interativo (ou seja, não executa um script), ele lê ~/.bashrc (exceto quando invocado como um shell de login, então ele só lê ~/.bash_profile ou ~/.profile.

Assim sendo:

  • ~/.profile é o lugar para colocar coisas que se aplicam a toda a sua sessão, como programas que você deseja iniciar quando efetua login (mas não programas gráficos, eles entram em um arquivo diferente) e definições de variáveis ​​de ambiente.

  • ~/.bashrc é o lugar para colocar coisas que se aplicam apenas ao bash, como alias e definições de função, opções de shell e configurações de prompt. (Você também pode colocar as teclas lá, mas elas normalmente entram em ~/.inputrc.)

  • ~/.bash_profile pode ser usado em vez de ~/.profile, mas é lido apenas por bash, não por qualquer outro shell. (Isso é principalmente uma preocupação se você quiser que seus arquivos de inicialização trabalhem em várias máquinas e que seu shell de login não seja um sucesso em todos eles.) Esse é um lugar lógico a ser incluído ~/.bashrc se o shell é interativo. Eu recomendo o seguinte conteúdo em ~/.bash_profile:

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

Nos sindicatos modernos, há uma complicação adicional relacionada ~/.profile. Se você efetuar login em um ambiente gráfico (ou seja, se o programa onde você digita sua senha estiver sendo executado no modo gráfico), você não receberá automaticamente um shell de login que leia ~/.profile. Dependendo do programa de login gráfico, no gerenciador de janelas ou no ambiente de área de trabalho que você executa posteriormente e em como sua distribuição configurou esses programas, ~/.profile pode ou não ser lido. Se não for, geralmente há outro local onde você pode definir variáveis ​​de ambiente e programas para iniciar quando você efetua login, mas infelizmente não há localização padrão.

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. Ambas são idéias ruins. O problema mais comum com qualquer uma dessas idéias é que suas variáveis ​​de ambiente só serão definidas em programas iniciados por meio do terminal, não em programas iniciados diretamente com um ícone ou menu ou atalho de teclado.

¹  Para completar, por solicitação: se .bash_profile não existe, o bash também tenta .bash_loginantes de voltar para .profile. Sinta-se livre para esquecer que existe.  


471



+1 para um bom post. TAMBÉM obrigado por adicionar seção sobre "login graphical vs login shell" ... Eu tive o problema onde eu pensei ~ / .profile SEMPRE executaria para graphical / shell ... mas ele não é executado quando o usuário efetua login via login gráfico. Obrigado por resolver esse mistério. - Trevor Boyd Smith
@Gilles: Você poderia explicar mais detalhadamente, com exemplos, por que executar um shell de login em cada terminal é uma má ideia? Isso é apenas um problema com o desktop Linux? (Eu entendo que no OS X Terminal roda uma shell de login todas as vezes, e eu nunca notei nenhum efeito colateral (embora eu geralmente uso o iTerm) .Mas então eu não consigo pensar em muitas variáveis ​​de ambiente que eu me importo fora um terminal (talvez HTTP_PROXY?)) - iconoclast
@Brandon Se você executar um shell de login em cada terminal, isso substituirá as variáveis ​​de ambiente fornecidas pelo ambiente. Em situações do dia-a-dia, você pode se safar, mas ele vai chegar mais cedo ou mais tarde, quando você quiser configurar variáveis ​​diferentes em um terminal (por exemplo, para experimentar uma versão diferente de um programa): O shell de login substituiria suas configurações locais. - Gilles
A declaração ~/.bash_profile pode ser usado em vez de ~/.profile, mas você também precisa incluir ~/.bashrc se o shell é interativo. é enganoso, pois são questões ortogonais. Não importa se você usa ~/.bash_profile ou ~/.profile você tem que incluir ~/.bashrc no que você usa se quiser que as configurações de lá tenham efeito no shell de login. - Piotr Dobrogost
@Gilles Claro, mas a forma como a frase é formulada na resposta sugere que a necessidade de incluir ~/.bashrc tem algo a ver com a escolha ~/.bash_profile ao invés de ~/.profile o que não é verdade. Se alguém incluir ~/.bashrc em qualquer tipo de script sendo originado no momento do login (aqui é ~/.bash_profile ou ~/.profile) é porque ele quer configurações de ~/.bashrc para ser aplicado ao shell de login da mesma maneira que eles estão sendo aplicados ao shell de não-login. - Piotr Dobrogost


Deste artigo curto

De acordo com a página man bash,   .bash_profile é executado para login   shells, enquanto .bashrc é executado para   shells não-login interativos.

O que é um shell de login ou não-login?

Quando você faz o login (por exemplo: digite o nome de usuário e   senha) via console, seja   fisicamente sentado na máquina quando   inicializando ou remotamente via ssh:   .bash_profile é executado para configurar   coisas antes do comando inicial   pronto.

Mas, se você já tiver logado   sua máquina e abra um novo terminal   janela (xterm) dentro do Gnome ou KDE,   então .bashrc é executado antes do   prompt de comando da janela. .bashrc também é   executado quando você inicia uma nova instância de bash   digitando / bin / bash em um terminal.


50



Ligeiras atualizações: 'Executado' é provavelmente um termo um pouco enganador, ambos são originados. Executado parece que é executado como um script, fork / exec yadda yadda. Ele é executado no contexto do shell atual Mais importante, o .bashrc é executado com muito mais frequência. Ele é executado em todas as execuções de script bash e também se você não tiver um .bash_profile. Além disso, dependendo de como você configura seus xterms, você pode criar um shell que origine .bash_profile - Rich Homolka


Nos velhos tempos, quando pseudo tty não era pseudo e, na verdade, bem, digitado, e UNIXes eram acessados ​​por modems tão lentos que você podia ver cada letra sendo impressa em sua tela, a eficiência era primordial. Para ajudar na eficiência, você teve um conceito de uma janela de login principal e de quaisquer outras janelas que você usou para realmente funcionar. Na sua janela principal, você gostaria de notificações para qualquer novo e-mail, possivelmente executar alguns outros programas em segundo plano.

Para suportar isso, shells originaram um arquivo .profile especificamente em 'shells de login'. Isso faria o especial, uma vez uma configuração de sessão. Bash estendeu isso um pouco para olhar para .bash_profile primeiro antes de .profile, dessa forma você poderia colocar apenas as coisas lá dentro (para que elas não estragassem o shell Bourne, etc, que também olhassem para .profile). Outros shells, non-login, apenas forneceriam o arquivo rc, .bashrc (ou .kshrc, etc).

Isso é um pouco de anacronismo agora. Você não entra em um shell principal, tanto quanto você faz login em um gerenciador de janelas GUI. Não há janela principal diferente de qualquer outra janela.

Minha sugestão - não se preocupe com essa diferença, ela é baseada em um estilo antigo de usar o unix. Elimine a diferença em seus arquivos. Todo o conteúdo de .bash_profile deve ser:

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

E coloque tudo o que você realmente deseja definir .bashrc

Lembre-se que .bashrc é originado para todos os shells, interativo e não interativo. Você pode causar curto-circuito no sourcing de shells não interativos colocando este código no topo do .bashrc:

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


34



Esta é uma má ideia, veja minha resposta. Em particular, suas variáveis ​​de ambiente só serão definidas em programas iniciados através do terminal, não em programas iniciados diretamente com um ícone ou menu ou atalho de teclado. - Gilles
@Gilles Eu não entendo porque você afirma isso. Com .$HOME/.bashrc como Rich mostrou acima, configurações em .bashrc estará disponível em shells de login e, portanto, no ambiente de desktop também. Por exemplo, no meu sistema Fedora, gnome-session é iniciado como -$SHELL -c gnome-session, assim .profile está lido. - Mikel
@PiotrDobrogost Oh, sim, há outro problema com a resposta de Rich. Incluindo .bashrc dentro .profile normalmente não funciona, porque .profile pode ser executado por /bin/sh e não bash (por exemplo, no Ubuntu para um login gráfico por padrão), e esse shell pode não ser interativo (por exemplo, para um login gráfico). - Gilles
@Gilles re: "incluindo .bashrc em .profile" não é de todo o que foi recomendado (pelo contrário, na verdade). Ou a resposta foi editada (não parece), ou seus comentários não se alinham com o que está sendo dito. - michael
Em geral, +1, mas gostaria de acrescentar à recomendação de "curto-circuito ... para shells não-interativos" ("perto do topo do .bashrc: [[ $- != *i* ]] && return"); Eu gosto de alguns dos meus .bashrc para ser executado mesmo para shells não interativos, especificamente para definir env vars, ao emitir ssh hostname {command}, para que os comandos remotos sejam executados corretamente (mesmo que o shell não seja interativo). Mas outras configurações posteriores .bashrc deve ser ignorado. Eu geralmente verifico TERM = mudo e / ou não definido, e depois saio cedo. - michael


Veja isso excelente postagem 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.

Para Bash, eles funcionam da seguinte maneira. Leia a coluna apropriada. Executa A, depois B, depois C, etc. O B1, B2, B3 significa que 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      |           |      |
+----------------+-----------+-----------+------+

14



Em vez de postar a mesma resposta em várias perguntas, é preferível que você possa adaptar sua resposta às necessidades específicas do interlocutor. Se a resposta for exatamente a mesma para as duas perguntas, você deverá postar uma única resposta e votar para fechar as outras perguntas como duplicatas do original. - Mokubai♦
@Mokubai A outra pergunta já foi marcada como uma duplicata desta. - Flimm
@ElipticalView: por set para não fazer nada, você está se referindo à linha: [ -z "$PS1" ] && return? A tabela na minha resposta está dando a lista de scripts executados pelo Bash independente do conteúdo dos scripts, se o próprio script tiver a linha [ -z "$PS1" ] && returnÉ claro que isso entraria em vigor, mas não acho que isso deva significar que eu deva mudar de mesa. - Flimm


UM COMENTÁRIO MELHOR PARA A CABEÇA DE / ETC / PERFIL

Construindo a grande resposta de Flimm acima, eu inseri este novo comentário na cabeça do meu Debian / etc / profile, (você pode precisar ajustá-lo para sua 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 esta nota na cabeça de cada um dos outros arquivos de configuração para se referir a ela:

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

Digno de nota eu acho que é o / etc / profile do Debian por default sources (includes) /etc/bash.bashrc (é quando o /etc/bash.bashrc existe). Portanto, os scripts de login lêem ambos os arquivos / etc, enquanto o não-login lê apenas o bash.bashrc.

Também é digno de nota que o /etc/bash.bashrc está configurado para não fazer nada quando não é executado de forma interativa. Portanto, esses dois arquivos são apenas para scripts interativos.


3