Ubuntu .bashrc, alias e PATH

Toda vez que você abre um terminal, o bash (o programa que lê o que você digita) executa um arquivo de configuração chamado ~/.bashrc. É ali que você cria atalhos (alias), define variáveis e diz onde o sistema deve procurar programas (o PATH).

Você vai aprender
  • O que são variáveis de ambiente e como ver o valor delas.
  • Como o bash encontra um programa quando você digita o nome dele (o PATH).
  • Criar alias temporários e permanentes, e de onde vem o ll do Ubuntu.
  • A diferença entre .bashrc, .profile e .bash_aliases.
  • Consertar o terminal quando uma edição dá errado.

Antes dos comandos: variáveis

Uma variável é um nome que guarda um valor. O bash já começa com várias delas, chamadas variáveis de ambiente, que os programas consultam para saber quem você é, qual é sua pasta pessoal e assim por diante. Para ler uma variável, coloque $ antes do nome:

echo
Mostra na tela o que recebeu.
$HOME
O $ pede ao bash para trocar o nome pelo valor da variável antes de rodar o echo.
$ echo $HOME
/home/ana
$ echo "Eu sou $USER e uso o editor $EDITOR"
Eu sou ana e uso o editor nano
VariávelGuardaExemplo
HOMESua pasta pessoal/home/ana
USERSeu nome de usuárioana
PATHOnde procurar programas/usr/local/bin:/usr/bin:…
PWDA pasta atual/home/ana/Documentos
SHELLO seu shell/bin/bash
LANGIdioma e formato regionalpt_BR.UTF-8
EDITOREditor padrão de alguns comandosnano (se definido)

Formas de ver variáveis

ComandoMostra
echo $NOMEUma variável. Se ela não existir, mostra uma linha vazia.
printenv NOMEUma variável de ambiente; devolve código 1 se ela não existir.
env ou printenvTodas as variáveis de ambiente.
env | grep -i langSó as que contêm "lang".
$ printenv LANG
pt_BR.UTF-8
$ printenv NADA
$ echo $?
1                                        « 1 = a variável não existe

PATH: onde o bash procura programas

Quando você digita ls, o bash não sabe de cara onde está o programa ls. Ele procura numa lista de pastas, na ordem, e usa o primeiro que encontrar. Essa lista é a variável PATH (em inglês, "caminho"). As pastas são separadas por dois-pontos:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Difícil de ler, não é? O tr troca cada : por uma quebra de linha:

echo $PATH
Imprime o PATH.
|
Entrega a saída ao próximo comando.
tr ':' '\n'
Translate: troca cada : por \n, a quebra de linha.
$ echo $PATH | tr ':' '\n'
/usr/local/sbin                          « procura aqui primeiro…
/usr/local/bin
/usr/sbin
/usr/bin                                 « …a maioria dos programas está aqui
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin                                « programas instalados por Snap

Para saber qual arquivo o bash vai rodar, use which ou type:

$ which python3
/usr/bin/python3
$ type -a ls
ls está apelidada para `ls --color=auto'          « primeiro vem o alias
ls é /usr/bin/ls
ls é /bin/ls

Se o programa não está em nenhuma pasta do PATH, o bash responde "comando não encontrado", mesmo que o arquivo exista em outro lugar.

Missão: veja o valor de $HOME e $USER com echo. Depois mostre o PATH com uma pasta por linha.

Acrescentar uma pasta ao PATH

Imagine que a Ana guarda seus scripts em ~/scripts e quer rodá-los pelo nome, de qualquer pasta. Ela acrescenta essa pasta no começo do PATH, sem apagar o resto:

export
Torna a variável visível para os programas que o bash abrir.
PATH=
Atribui um novo valor ao PATH. Sem espaços em volta do =.
"$HOME/scripts
A pasta nova…
:$PATH"
…seguida de dois-pontos e do PATH antigo. Nunca esqueça o $PATH.
$ export PATH="$HOME/scripts:$PATH"
$ echo $PATH | tr ':' '\n' | head -3
/home/ana/scripts
/usr/local/sbin
/usr/local/bin

Isso vale só para este terminal. Para ficar permanente, coloque a mesma linha no fim do ~/.bashrc (veja abaixo).

A pasta ~/.local/bin já vem pronta

O ~/.profile do Ubuntu já põe ~/bin e ~/.local/bin no PATH, se essas pastas existirem. Basta criar a pasta, guardar os scripts nela e sair e entrar de novo na sessão.


export: variáveis para os outros programas

Uma variável criada sem export existe só dentro do bash atual. Os programas que ele abre não a enxergam. Veja a diferença (o bash -c abre um bash "filho" que roda um comando):

$ CIDADE=Recife
$ echo $CIDADE
Recife
$ bash -c 'echo "o filho vê: [$CIDADE]"'
o filho vê: []                           « sem export, o filho não enxerga
$ export CIDADE
$ bash -c 'echo "o filho vê: [$CIDADE]"'
o filho vê: [Recife]

Regra prática: use export para tudo que um programa precisa ler (PATH, EDITOR, chaves de API…).


alias: atalhos para comandos

Um alias ("apelido") é um nome curto que o bash troca por um comando maior. O Ubuntu já vem com alguns. Para ver todos, digite alias:

$ alias
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'                       « por isso o ll funciona
alias ls='ls --color=auto'               « e por isso o ls tem cores

Criar um alias

alias
O comando que cria apelidos.
atualizar=
O nome do atalho. Sem espaço antes nem depois do =.
'sudo apt update && sudo apt upgrade'
O comando completo, entre aspas simples.
$ alias atualizar='sudo apt update && sudo apt upgrade'
$ type atualizar
atualizar está apelidada para `sudo apt update && sudo apt upgrade'
$ atualizar
[sudo: authenticate] Senha:
Atingido:1 http://br.archive.ubuntu.com/ubuntu resolute InRelease
…

Para remover: unalias atualizar. Assim como as variáveis, esse alias some quando você fecha o terminal.

Ideias de alias úteis

AliasPara quê
alias rm='rm -i'Pergunta antes de apagar cada arquivo.
alias ..='cd ..'Subir uma pasta digitando só ..
alias ip='ip -c'Saída colorida do ip.
alias meuip='hostname -I'Ver o IP da máquina.
alias espaco='df -h -x tmpfs -x squashfs'Espaço em disco sem os sistemas virtuais.

Um alias com o mesmo nome de um comando "ganha" dele. Para rodar o comando original uma vez, coloque uma barra antes: \rm arquivo.


Tornar permanente: os arquivos de configuração

Para que alias, variáveis e PATH sobrevivam ao fechar o terminal, eles precisam estar num arquivo que o bash lê sozinho. Qual arquivo depende de quando você quer que a configuração valha:

ArquivoQuando é lidoColoque aqui
~/.bashrcCada terminal interativo que você abreAlias, funções, aparência do prompt, PATH para o terminal.
~/.bash_aliasesLido pelo .bashrc do Ubuntu, se existirSó os seus alias, separados e organizados.
~/.profileUma vez, ao entrar na sessão (gráfica ou SSH)Variáveis que programas gráficos também precisam ver.
/etc/environmentPara todos os usuários, no loginVariáveis do sistema todo (formato NOME="valor", sem export).

O .bashrc do Ubuntu já tem estas linhas, que leem o ~/.bash_aliases:

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Passo a passo: alias permanente

  1. Acrescente o alias no fim do ~/.bash_aliases. O >> acrescenta sem apagar o que já existe (e cria o arquivo se ele não existir):

    $ echo "alias atualizar='sudo apt update && sudo apt upgrade'" >> ~/.bash_aliases

    Para editar com mais calma, use nano ~/.bash_aliases.

  2. Recarregue a configuração no terminal atual. O source lê o arquivo de novo sem fechar o terminal:

    source
    Executa um arquivo dentro do shell atual. Também pode ser escrito só como .
    ~/.bashrc
    O arquivo a reler (ele também lê o .bash_aliases).
    $ source ~/.bashrc
    $ type atualizar
    atualizar está apelidada para `sudo apt update && sudo apt upgrade'
  3. Teste num terminal novo (Ctrl+Alt+T). O alias deve continuar lá.

Outras configurações comuns no .bashrc

# meus scripts no PATH
export PATH="$HOME/scripts:$PATH"

# editor padrão para crontab, git, visudo…
export EDITOR=nano

# guardar mais comandos no histórico
HISTSIZE=10000
HISTFILESIZE=20000

O Ubuntu já vem com HISTSIZE=1000 e HISTCONTROL=ignoreboth, que não guarda comandos repetidos nem os que começam com espaço. Isso é útil para não deixar senhas no histórico.

Faça uma cópia antes de editar

Um erro no .bashrc aparece toda vez que você abre um terminal. Antes de mexer, rode cp ~/.bashrc ~/.bashrc.bak. Se algo der errado, volte com cp ~/.bashrc.bak ~/.bashrc.


Quando não funciona

Editei o .bashrc e nada mudou

O que aconteceu: o .bashrc só é lido quando um terminal abre. O terminal atual ainda usa a configuração antiga.

Como resolver: rode source ~/.bashrc ou abra um terminal novo. Se você editou o .profile, é preciso sair da sessão e entrar de novo.

"comando não encontrado" para tudo
$ export PATH="$HOME/scripts"
$ ls
Comando 'ls' está disponível nos seguintes locais
 * /bin/ls
 * /usr/bin/ls
O comando não foi localizado porque '/bin:/usr/bin' não está incluído na variável de ambiente PATH.
ls: comando não encontrado

O que aconteceu: o :$PATH ficou de fora, e o PATH passou a ter uma pasta só. O bash não acha mais nenhum programa.

Como resolver no terminal atual: restaure o padrão do Ubuntu:

$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

Depois corrija a linha no .bashrc com nano ~/.bashrc. Se o erro estiver no arquivo, todo terminal novo nasce quebrado; nesse caso use o caminho completo do editor: /usr/bin/nano ~/.bashrc.

"nome: comando não encontrado" ao criar variável
$ CIDADE = Recife
CIDADE: comando não encontrado

O que aconteceu: com espaços em volta do =, o bash entende que CIDADE é um comando e = e Recife são argumentos.

Como resolver: escreva sem espaços: CIDADE=Recife. O mesmo vale para alias nome='…'.

O terminal abre e mostra um erro, ou fecha na hora
bash: /home/ana/.bashrc: linha 121: erro de sintaxe: fim inesperado do arquivo do comando `if' na linha 118

O que aconteceu: faltou fechar uma aspa ou um fi no .bashrc. A linha informada é onde o bash percebeu o problema, não necessariamente onde ele está.

Como resolver: abra um bash que ignora o arquivo e corrija: bash --norc, depois nano ~/.bashrc. Se o terminal gráfico fecha na hora, use um TTY (Ctrl+Alt+F3; veja Quando o Sistema Trava) ou volte o backup.

Comandos com sudo não veem meu PATH ou alias

O que aconteceu: o sudo usa um PATH próprio e seguro, e não lê os seus alias. sudo meuscript responde "command not found" mesmo que meuscript funcione sem sudo.

Como resolver: use o caminho completo (sudo ~/scripts/meuscript) ou instale o script em /usr/local/bin.


Referência

ComandoO que faz
echo $VARMostra o valor de uma variável
VAR=valorCria uma variável no shell atual
export VAR=valorCria e torna visível para os programas abertos pelo shell
unset VARApaga a variável
env / printenvLista as variáveis de ambiente
aliasLista os alias
alias nome='comando'Cria um alias
unalias nomeRemove um alias
type nomeDiz se é alias, comando interno ou programa
which nomeMostra o caminho do programa
source arquivoLê um arquivo no shell atual
bash --norcAbre um bash sem ler o .bashrc

Exercícios

1. Ler uma variável

Complete para mostrar a pasta pessoal:

echo

2. PATH sem quebrar

Complete para acrescentar ~/bin no começo do PATH, mantendo o resto:

export PATH="$HOME/bin:"

3. Recarregar

Complete para aplicar as mudanças do .bashrc sem fechar o terminal:

~/.bashrc

4. Onde colocar um alias para ele valer em todo terminal novo?

5. Depois de export PATH="/opt/app", nenhum comando funciona. Por quê?


Resumo

  • $NOME lê uma variável; export a torna visível para outros programas.
  • O PATH é a lista de pastas onde o bash procura programas. Acrescente com PATH="nova:$PATH".
  • alias nome='comando' cria atalhos; o ll do Ubuntu é um alias.
  • Para ficar permanente: ~/.bashrc ou ~/.bash_aliases, depois source ~/.bashrc.
  • Sem espaços em volta do =. Faça backup do .bashrc antes de editar.