Diferença entre .bashrc e .bash_profile
Qual é a diferença entre .bashrc
e .bash_profile
e qual devo usar?
Qual é a diferença entre .bashrc
e .bash_profile
e qual devo usar?
Tradicionalmente, quando se entra num sistema Unix, o sistema inicia um programa para si. Esse programa é uma shell, ou seja, um programa concebido para iniciar outros programas. É uma shell de linha de comando: inicia-se outro programa ao digitar o seu nome. A shell padrão, uma shell Bourne, lê comandos de ~/.profile
quando é invocada como a shell de login.
Bash é uma shell do tipo Bourne. Lê comandos de ~/.bash_profile
quando é invocada como shell de início de sessão, e se esse ficheiro não existir¹, tenta ler ~/.profile
em vez disso.
Pode invocar uma shell directamente em qualquer altura, por exemplo, lançando um emulador de terminal dentro de um ambiente GUI. Se a shell não for uma shell de login, não lê ~/.profile
. Quando começa a funcionar como uma shell interactiva (ou seja, para não executar um script), lê ~/.bashrc
(excepto quando invocada como shell de início de sessão, então lê apenas ~/.bash_profile
ou ~/.profile
.
& Portanto:
~/.profile
é o local para colocar coisas que se aplicam a toda a sua sessão, tais como programas que deseja iniciar quando iniciar sessão (mas não programas gráficos, eles vão para um ficheiro diferente), e definições de variáveis de ambiente. & - ~/.bashrc
é o lugar para colocar coisas que se aplicam apenas a si próprio, tais como alias e definições de funções, opções de shell, e definições rápidas. (Também se poderia colocar ali ligaduras de chave, mas para bater, normalmente vão para ~/.inputrc
.)
~/.bash_profile
pode ser usado em vez de ~/.profile
, mas é lido apenas por bash, e não por qualquer outra shell. (Isto é sobretudo uma preocupação se quiser que os seus ficheiros de inicialização funcionem em múltiplas máquinas e a sua shell de início de sessão não se baseia em todas elas). Este é um local lógico para incluir ~/.bashrc
se a shell for interactiva. Recomendo os seguintes conteúdos em ~/.bash_profile
: Em unices modernos, há uma complicação adicional relacionada com ~/.profile
. Se iniciar sessão num ambiente gráfico (isto é, se o programa onde escreve a sua palavra-passe estiver a correr em modo gráfico), não obtém automaticamente uma shell de início de sessão que lê ~/.profile
. Dependendo do programa gráfico de login, do gestor de janelas ou do ambiente de trabalho que executa depois, e de como a sua distribuição configurou estes programas, o seu ~/.profile
pode ou não ser lido. Se não for, há normalmente outro local onde pode definir variáveis de ambiente e programas a lançar quando faz o login, mas infelizmente não há um local padrão.
Note que pode ver aqui e ali recomendações para colocar definições de variáveis de ambiente em ~/.bashrc
ou lançar sempre shells de início de sessão em terminais. Ambas são más ideias. O problema mais comum com qualquer uma destas ideias é que as variáveis de ambiente só serão definidas em programas lançados através do terminal, não em programas iniciados directamente com um ícone ou menu ou atalho de teclado.
¹ Para completar, por pedido: se .bash_profile
não existir, bash também tenta .bash_login
antes de cair de novo para .profile
. Sinta-se à vontade para esquecer que ele existe.
A partir deste breve artigo
De acordo com a página bash man, .bash_profile é executado para shells de login, enquanto .bashrc é executado para shells não-login interactivas.
& > O que é uma shell de login ou não de login? & > Quando faz login (por exemplo: digite nome de utilizador e palavra-passe) via consola, quer fisicamente sentado na máquina ao arrancar, ou remotamente via ssh: .bash_profile é executado para configurar coisas antes do prompt de comando inicial.
Mas, se já entrou na sua máquina e abrir uma nova janela de terminal (xterm) dentro do Gnome ou KDE, então o .bashrc é executado antes do prompt de comando da janela. O .bashrc também é executado quando inicia uma nova instância de bash digitando /bin/bash num terminal.
Antigamente, quando os pseudo tty’s não eram pseudo e, na verdade, bem, os UNIX’s eram acedidos por modems tão lentos que se podia ver cada letra a ser impressa no seu ecrã, a eficiência era primordial. Para ajudar um pouco a eficiência, tinha um conceito de uma janela de login principal e quaisquer outras janelas que utilizasse para trabalhar de facto. Na sua janela principal, gostaria de receber notificações para qualquer novo correio, possivelmente executar alguns outros programas em segundo plano.
Para suportar isto, as shells têm como fonte um ficheiro .profile
especificamente em ‘shells de início de sessão’. Isto faria o especial, uma vez uma sessão configurada. Bash estendeu isto um pouco para olhar para .bash_profile primeiro antes de .profile, desta forma poderia colocar lá apenas coisas bash (para que não lixem Bourne shell, etc., que também olhavam para .profile). Outras conchas, não-login, apenas iriam buscar o ficheiro rc, .bashrc (ou .kshrc, etc).
Isto agora é um pouco de anacronismo. Não se entra tanto numa shell principal como se entra num gestor de janelas gui. Não há nenhuma janela principal diferente de qualquer outra janela.
A minha sugestão - não se preocupe com esta diferença, é baseada num estilo mais antigo de utilização do unix. Elimine a diferença nos seus ficheiros. Todo o conteúdo do ficheiro .bash_profile deve ser:
[-f $HOME/.bashrc] && . $HOME/.bashrc
E ponha tudo o que realmente quiser definir em .bashrc
Lembre-se de que .bashrc é fonte para todos os shells, interactivo e não interactivo. Pode fazer um curto-circuito na origem para shells não interactivas colocando este código perto do topo de .bashrc:
[[$- != *i*]] && return
Veja este excelente post no blogue por ShreevatsaR . Aqui está um extracto, mas vá ao post do blogue, ele inclui uma explicação para termos como “shell de login”, um diagrama de fluxo, e uma tabela semelhante para Zsh.
Para Bash, eles funcionam da seguinte forma. Leia abaixo a coluna apropriada. Executa A, depois B, depois C, etc. O B1, B2, B3 significa que executa apenas o primeiro dos ficheiros 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 | | |
+----------------+-----------+-----------+------+
Um COMENTÁRIO MELHOR PARA A CABEÇA DE /ETC/PROFILE
Construindo sobre a grande resposta de Flimm acima, inseri este novo comentário na cabeça do meu Debian /etc/profile, (talvez seja necessário ajustá-lo para a 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 ficheiros de configuração para se referir a ela:
# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE
Vale a pena notar que penso que o /etc/profile da Debian por defeito (inclui) /etc/bash.bashrc (é quando o /etc/bash.bashrc existe). Assim, os scripts de login lêem ambos os ficheiros /etc, enquanto que os ficheiros não-login só lêem o /etc/bash.bashrc.
Também de notar que o /etc/bash.bashrc está configurado para não fazer nada quando não é executado interactivamente. Portanto, estes dois ficheiros são apenas para scripts interactivos.
A lógica de configuração da bash em si não é complicada e explicada noutras respostas nesta página, na falha do servidor e em muitos blogs. O problema no entanto é o que as distribuições Linux fazem da bash, refiro-me às complexas e várias formas como configuram a bash por defeito. http://mywiki.wooledge.org/DotFiles menciona brevemente algumas destas peculiaridades. Aqui está um exemplo de traço no Fedora 29, que mostra que ficheiros originam que outro(s) ficheiro(s) e em que ordem para um cenário muito simples: ligação remota com o ssh e depois iniciar outra subesquema:
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á em /etc/bashrc
. Como se viu acima /etc/bashrc
é um ficheiro que não se conhece, ou seja, não directamente. A /etc/bashrc
de Fedora testa se:
& … e depois faz coisas completamente diferentes, dependendo delas.
~/.profile
. Omiti bash_completion
scripts. Por razões de retrocompatibilidade, invocar bash como /bin/sh
em vez de /bin/bash
altera o seu comportamento. E quanto ao zsh e outras conchas? E claro que diferentes distribuições Linux fazem as coisas de forma diferente, por exemplo Debian e Ubuntu vêm com uma versão não standard do bash, tem personalização(ões) específica(s) de Debian. Procura, nomeadamente, um ficheiro invulgar: /etc/bash.bashrc
. Mesmo que se limite a uma única distribuição Linux, ele provavelmente evolui ao longo do tempo. Espere: nem sequer tocámos em macOS, FreeBSD,… Finalmente, vamos ter uma ideia para os utilizadores presos às formas ainda mais criativas que os seus administradores configuraram o sistema que têm de utilizar. Como o fluxo interminável de discussões sobre este tema demonstra, é uma causa perdida. Desde que se pretenda apenas acrescentar novos valores, alguma “tentativa e erro” tende a ser suficiente. A verdadeira diversão começa quando se quer modificar num ficheiro (utilizador) algo já definido noutro (em /etc). Depois esteja preparado para passar algum tempo a conceber uma solução que nunca será portátil.
Para uma última diversão aqui está o “gráfico de origem” para o mesmo, cenário simples no Clear Linux 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