Diferença entre .bashrc e .bash_profile

449

Qual é a diferença entre .bashrce .bash_profilee qual deles devo usar?

cfischer
fonte
2
Veja também esta pergunta semelhante na ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
Stefan Lasiewski
Se você quer uma explicação mais completa que envolve também .profile, ter um olhar para esta questão: superuser.com/questions/789448/...
Flimm
Esta resposta também cobre alguns aspectos stackoverflow.com/questions/415403/…
Sergey Voronezhskiy

Respostas:

517

Tradicionalmente, quando você faz login 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 a partir de ~/.profilequando é chamado como o shell de logon.

Bash é uma concha tipo Bourne. Ele lê comandos a partir de ~/.bash_profilequando é chamado como o shell de logon e, se esse arquivo não existir¹, ele tenta ler ~/.profile.

Você pode chamar um shell diretamente a qualquer momento, por exemplo, iniciando um emulador de terminal dentro de um ambiente da GUI. Se o shell não for um shell de logon, ele não será lido ~/.profile. Quando você inicia o bash como um shell interativo (ou seja, para não executar um script), ele lê ~/.bashrc(exceto quando chamado como um shell de logon, então ele lê apenas ~/.bash_profileou ~/.profile.

Portanto:

  • ~/.profile é o local para colocar itens que se aplicam a toda a sessão, como programas que você deseja iniciar quando efetuar 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 de atalho lá, mas para o bash elas normalmente entram ~/.inputrc.)

  • ~/.bash_profilepode ser usado em vez de ~/.profile, mas é lido apenas pelo bash, não por qualquer outro shell. (Isso é principalmente uma preocupação se você deseja que seus arquivos de inicialização funcionem em várias máquinas e seu shell de logon não seja baseado em todas elas.) Esse é um local lógico para incluir ~/.bashrcse o shell for 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 escritórios modernos, há uma complicação adicional relacionada a ~/.profile. Se você efetuar login em um ambiente gráfico (ou seja, se o programa em que você digitar sua senha estiver em execução no modo gráfico), não receberá automaticamente um shell de login que lê ~/.profile. Dependendo do programa de login gráfico, do gerenciador de janelas ou do ambiente de trabalho executado posteriormente e de como sua distribuição configurou esses programas, você ~/.profilepode ou não ser lido. Caso contrário, geralmente há outro local onde você pode definir variáveis ​​de ambiente e programas a serem iniciados quando efetuar login, mas infelizmente não há local padrão.

Observe que você pode ver aqui e ali recomendações para colocar definições de variáveis ​​de ambiente ~/.bashrcou sempre iniciar shells de login nos terminais. Ambos são más idéias. O problema mais comum de qualquer uma dessas idéias é que suas variáveis ​​de ambiente serão definidas apenas em programas iniciados pelo terminal, não em programas iniciados diretamente com um ícone ou menu ou atalho de teclado.

¹ Para completar, por solicitação: se .bash_profilenão existir, o bash também tenta .bash_loginantes de retornar ao .profile. Sinta-se livre para esquecer que existe.

Gilles
fonte
11
+1 para uma boa postagem. TAMBÉM obrigado por adicionar a seção sobre "login gráfico versus shell de login" ... Eu tive o problema em que pensei que o ~ / .profile SEMPRE executaria para o gráfico / shell ... mas não é executado quando o usuário faz login via login gráfico. Obrigado por resolver esse mistério.
Trevor Boyd Smith
4
@ Gilles: Você poderia explicar com mais detalhes, com exemplos, por que executar uma shell de login em cada terminal é uma má ideia? Isso é apenas um problema no Linux para desktop? (Eu acho que no OS X Terminal sempre é executado um shell de logon e nunca notei efeitos colaterais (embora eu costumo usar o iTerm). Mas não consigo pensar em muitas variáveis ​​de ambiente que me interessariam fora de Um terminal. (Talvez HTTP_PROXY?))
iconoclast
2
@Brandon Se você executar um shell de login em todos os terminais, isso substituirá as variáveis ​​de ambiente fornecidas pelo ambiente. Em situações cotidianas, você pode se safar, mas ele vai te morder mais cedo ou mais tarde, quando você deseja configurar variáveis ​​diferentes em um terminal (por exemplo, para experimentar uma versão diferente de um programa): executando um o shell de login substituirá suas configurações locais.
Gilles
4
A instrução ~/.bash_profilepode ser usada em vez de ~/.profile, mas você também precisa incluir ~/.bashrcse o shell é interativo. é enganoso, pois são questões ortogonais. Não importa se você usa ~/.bash_profileou ~/.profileprecisa incluir ~/.bashrcno que você usa, se deseja que as configurações de lá tenham efeito no shell de login.
Piotr Dobrogost
3
@ Gilles Claro, mas a maneira como a frase é formulada na resposta sugere que a necessidade de incluir ~/.bashrctem algo a ver com a escolha, em ~/.bash_profilevez de ~/.profilenão ser verdade. Se alguém inclui que ~/.bashrcqualquer tipo de script seja originado no momento do login (aqui é ~/.bash_profileou ~/.profile) é porque ele deseja que as configurações ~/.bashrcsejam aplicadas ao shell de login da mesma forma que estão sendo aplicadas ao shell que não é de login.
Piotr Dobrogost
53

Deste breve artigo

De acordo com a página de manual do bash, .bash_profile é executado para shells de logon, enquanto .bashrc é executado para shells interativos sem logon.

O que é um shell de logon ou não logon?

Quando você faz login (por exemplo: digite nome de usuário e senha) no console, sentado fisicamente na máquina durante a inicialização ou remotamente via ssh: .bash_profile é executado para configurar as coisas antes do prompt de comando inicial.

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

Jarvin
fonte
12
Pequenas atualizações: 'Executado' é provavelmente um termo um pouco enganador, ambos são de origem. Os sons executados são executados como um script, fork / exec yadda yadda. É executado no contexto do shell atual Mais importante, o .bashrc é executado com muito mais frequência. É executado em todos os scripts do 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
36

Antigamente, quando os pseudo-tty não eram pseudo-e, na verdade, bem, datilografavam, e os UNIX eram acessados ​​por modems tão lentos que era possível ver cada letra sendo impressa na tela, a eficiência era primordial. Para ajudar um pouco a eficiência, você tinha o conceito de uma janela principal de login e quaisquer outras janelas que costumava trabalhar. Na janela principal, você gostaria de receber notificações sobre novos emails, possivelmente executando outros programas em segundo plano.

Para dar suporte a isso, os shells originaram um arquivo .profileespecificamente em 'shells de login'. Isso faria o especial, uma vez que a configuração da sessão. O Bash estendeu um pouco isso para examinar o .bash_profile antes do .profile, dessa forma, você pode colocar apenas o bash nas coisas (para que elas não estraguem o shell Bourne, etc., que também olham para o .profile). Outros shells, sem logon, apenas forneceriam o arquivo rc, .bashrc (ou .kshrc, etc).

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

Minha sugestão - não se preocupe com essa diferença, ela se baseia 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 configurar no .bashrc

Lembre-se de que o .bashrc é fornecido para todos os shells, interativos e não interativos. Você pode causar um curto-circuito na fonte de shells não interativos colocando esse código próximo à parte superior de .bashrc:

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

Rich Homolka
fonte
6
Esta é uma péssima ideia, veja minha resposta . Em particular, suas variáveis ​​de ambiente serão definidas apenas em programas iniciados pelo terminal, não em programas iniciados diretamente com um ícone ou menu ou atalho de teclado.
Gilles
4
@ Gilles Eu não entendo por que você afirma isso. Com .$HOME/.bashrco Rich mostrado acima, as configurações em .bashrcestarão disponíveis nos shells de login e, portanto, no ambiente da área de trabalho. Por exemplo, no meu sistema Fedora, gnome-sessioné iniciado como -$SHELL -c gnome-session, e também .profileé lido.
Mikel
2
@PiotrDobrogost Oh, sim, há outro problema com a resposta de Rich. Incluindo .bashrcno .profilenormalmente não funciona, porque .profilepode ser executado por /bin/she não bash (por exemplo, no Ubuntu para um login gráfico por padrão), e que a Shell pode não ser interativa (por exemplo, para um login gráfico).
Gilles
3
@Gilles re: "incluir .bashrc em .profile" não é o recomendado (pelo contrário, de fato). A resposta foi editada (parece que não) ou seus comentários não estão alinhados com o que está sendo dito.
31513 Michael
2
Em geral, +1, mas eu acrescentaria à recomendação "curto-circuito ... para shells não interativos" ("próximo ao topo de .bashrc: [[ $- != *i* ]] && return"); Eu gosto que alguns dos meus .bashrcsejam executados mesmo para shells não interativos, especificamente para definir env vars, quando emitidos ssh hostname {command}, para que os comandos remotos sejam executados corretamente (mesmo que o shell não seja interativo). Porém, outras configurações posteriores .bashrcdevem ser ignoradas. Normalmente, procuro TERM = burro e / ou desabilitado e depois saio cedo.
31513 Michael
18

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
Em vez de postar a mesma resposta em várias perguntas, é preferível que você possa adaptar sua resposta às necessidades específicas do solicitante. 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
1
@Mokubai A outra pergunta já foi marcada como duplicada desta.
Flimm
@ElipticalView: ao definir para não fazer nada, você está se referindo à linha [ -z "$PS1" ] && return:? A tabela na minha resposta está fornecendo a lista de scripts executados pelo Bash, independentemente do conteúdo dos scripts, se o próprio script tiver a linha [ -z "$PS1" ] && return, é claro que isso entraria em vigor, mas acho que isso não significa que devo alterar o mesa.
Flimm
5

MELHOR COMENTÁRIO PARA O CABEÇOTE / ETC / PERFIL

Com base na grande resposta de Flimm acima, eu insered este novo comentário na cabeça do meu Debian / etc / profile, (pode ser necessário 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 instalação para se referir a ele:

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

Vale ressaltar que eu acho que é o / etc / profile do Debian por fontes padrão (inclui) /etc/bash.bashrc (é quando o /etc/bash.bashrc existe). Portanto, os scripts de login leem os arquivos / etc, enquanto o não-login lê apenas o bash.bashrc.

Também é importante notar 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.

Vista elíptica
fonte
4

A lógica de configuração do próprio bash não é muito complicada e explicada em outras respostas nesta página, em falha do servidor e em muitos blogs. O problema, porém, é o que as distribuições Linux fazem do bash , refiro-me às formas complexas e variadas em que eles configuram o bash por padrão. http://mywiki.wooledge.org/DotFiles menciona brevemente algumas dessas peculiaridades. Aqui está um exemplo de rastreio no Fedora 29, que mostra quais arquivos originam quais outros arquivos e em que ordem para um cenário muito simples: conectando-se remotamente ao ssh e iniciando outro subshell:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      |    ├─ /etc/profile.d/*.sh
      |    ├─ /etc/profile.d/sh.local
      |    └─ /etc/bashrc
      ├── ~/.bash_profile
      |    └─ ~/.bashrc
      |          └─ /etc/bashrc
      |
      |
      └─ $ bash  # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

A lógica mais complexa do Fedora está dentro /etc/bashrc. Como visto acima, o /etc/bashrcarquivo bash não conhece, quero dizer, não diretamente. Os /etc/bashrctestes do Fedora se:

  • está sendo fornecido por um shell de login,
  • está sendo originado por um shell interativo,
  • já foi adquirido

... e depois faz coisas completamente diferentes, dependendo delas.

Se você acha que consegue se lembrar do gráfico acima, é muito ruim porque não é o suficiente: este gráfico descreve apenas apenas um cenário, coisas ligeiramente diferentes acontecem ao executar scripts não interativos ou ao iniciar uma sessão gráfica. Eu omiti ~/.profile. Omiti bash_completionscripts. Por motivos de compatibilidade com versões anteriores, invocar o bash como em /bin/shvez de /bin/bashalterar seu comportamento. E o zsh e outras conchas? E é claro que diferentes distribuições Linux fazem as coisas de maneira diferente, por exemplo, o Debian e o Ubuntu vêm com uma versão não-padrão do bas h, com customizações específicas do Debian. Ele procura especialmente um arquivo incomum:/etc/bash.bashrc. Mesmo se você se ater a uma única distribuição Linux, ela provavelmente evoluirá com o tempo. Espere: nós nem sequer tocamos no macOS, no FreeBSD, ... Finalmente, vamos pensar nos usuários presos às formas ainda mais criativas que seus administradores configuraram no sistema que precisam usar.

Como o fluxo interminável de discussões sobre este tópico demonstra, é uma causa perdida. Contanto que você queira adicionar novos valores, algumas "tentativas e erros" tendem a ser suficientes. A verdadeira diversão começa quando você deseja modificar em um arquivo (usuário) algo já definido em outro (em / etc). Em seguida, esteja preparado para gastar algum tempo criando uma solução que nunca será portátil.

Para um pouco de diversão, aqui está o "gráfico de origem" do mesmo cenário simples no Clear Linux a partir de junho de 2019:

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      |    ├─ /usr/share/defaults/etc/profile.d/*
      |    ├─ /etc/profile.d/*
      |    └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─  $ bash   # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           |      ├─ /usr/share/defaults/etc/profile
           |      |    ├─ /usr/share/defaults/etc/profile.d/*
           |      |    ├─ /etc/profile.d/*
           |      |    └─ /etc/profile
           |      └─ /etc/profile
           └─ ~/.bashrc
Marcha
fonte