Corrigindo Erros "command not found" - Soluções Quando Comandos Estão Ausentes

Corrigindo Erros "command not found" - Soluções Quando Comandos Estão Ausentes

O Que Você Vai Aprender

  • Diagnosticar erros command not found em menos de 30 segundos
  • Reconhecer padrões típicos para PATH / hash / sudo / cron
  • Parar o problema "eu instalei mas não encontra" de acontecer novamente

Resumo Rápido

  1. Verifique a existência com command -v <nome>
  2. Mostre os caminhos de busca com echo $PATH
  3. A causa é quase sempre uma destas: pacote ausente / PATH não configurado / cache hash obsoleto / secure_path do sudo / erro de digitação

Ambiente Alvo

  • SO: Ubuntu / Debian (apt). Família RHEL (dnf / yum) incluída quando relevante
  • Shell: bash / zsh

1. As 5 Causas Raiz

Conclusão: As causas são: pacote ausente, PATH, hash obsoleto, secure_path do sudo ou erro de digitação.

Quase todo erro command not found se resume a uma destas:

# Causa Chave de diagnóstico
1 Comando não está instalado apt-cache search / dnf provides
2 Executável não está no PATH echo $PATH / which -a
3 Cache hash do shell está obsoleto hash -r
4 Restrição de secure_path do sudo sudo -V / secure_path em /etc/sudoers
5 Erro de digitação (maiúsculas / ortografia) type / compgen -c

80% dos casos são #2 PATH ou #3 hash. Sempre verifique esses dois primeiro.

2. Passos de Diagnóstico (Template de 30 Segundos)

Conclusão: Use command -v para verificar, echo $PATH para inspecionar e depois busque o pacote.

2-1. Verifique a existência primeiro

$ command -v ansible
  • Saída presente --> o comando está visível. Se ainda falhar, é um problema de permissão (não command not found).
  • Sem saída --> continue para 2-2.

command -v é padrão POSIX. O comportamento de which varia por distro (o which do Debian retorna apenas um código de saída), então prefira command -v em scripts. Use type para investigação, pois ele distingue alias / função / builtin / arquivo.

2-2. Mostre o PATH

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

Verifique se o diretório de instalação esperado está no PATH. Diretórios comuns:

  • ~/.local/bin (pip install --user / pipx)
  • ~/bin (adicionado automaticamente pelo ~/.profile do Ubuntu, mas apenas para login shells do bash)
  • /usr/local/bin (ferramentas compiladas manualmente)
  • /snap/bin (instalados via snap)

2-3. Busque o pacote

Se o comando não está instalado, descubra qual pacote o fornece.

# Ubuntu / Debian
$ apt-cache search ^ansible$
$ /usr/lib/command-not-found ansible    # dica util do Ubuntu
# RHEL / Fedora
$ dnf provides '*/ansible'

3. Correções Caso a Caso

Conclusão: As correções variam por caso: instalação recente, pip ou npm, erro de digitação e troca de shell.

3-1. Acabou de instalar mas ainda não encontra

O shell armazenou em cache um caminho antigo via hash.

$ hash -r          # funciona tanto no bash quanto no zsh
$ rehash           # idioma do zsh

Se isso não ajudar, ou o diretório bin do novo pacote não está no PATH, ou você instalou como um usuário diferente (ex: root).

3-2. pip install --user command not found

O local de instalação é ~/.local/bin. Adicione ao PATH.

$ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc

Para CLIs Python, prefira pipx. Executar pipx ensurepath configura o PATH automaticamente, então é mais seguro que pip install --user.

3-3. npm install -g command not found

Verifique o prefixo de instalação com npm config get prefix. Se for /usr/local, você pode ter um problema de permissão. Se for um prefixo personalizado como ~/.npm-global, adicione seu bin ao PATH.

$ npm config get prefix
$ ls "$(npm config get prefix)/bin"

3-4. Sensibilidade a maiúsculas / erro de digitação

Nomes de arquivo no Linux são sensíveis a maiúsculas e minúsculas.

$ Vim file.txt      # --> command not found
$ vim file.txt      # OK

Liste candidatos:

$ compgen -c vim    # comandos que comecam com "vim"

3-5. Não encontra após trocar de shell

Ao trocar de bash --> zsh, o arquivo onde o PATH é configurado muda.

Shell Login shell Shell interativo
bash ~/.bash_profile --> ~/.profile ~/.bashrc
zsh ~/.zprofile ~/.zshrc

~/.profile é lido por shells POSIX. ~/.bashrc é exclusivo do bash e não é lido pelo zsh. Se você trocar para zsh, mova suas configurações de PATH para ~/.zshrc.

4. Persistindo o PATH Corretamente

Conclusão: Sempre adicione ao $PATH, nunca sobrescreva; use /etc/profile.d para todo o sistema.

4-1. Padrão recomendado

# No final de ~/.bashrc ou ~/.zshrc
export PATH="$HOME/.local/bin:$PATH"
  • A ordem (antes vs. depois de $PATH) controla a prioridade
  • Coloque seus scripts personalizados antes de $PATH para sobrescrever comandos do sistema
  • Coloque-os depois para deixar os comandos do sistema prevalecerem

4-2. PATH para todo o sistema

Use /etc/profile.d/*.sh. Note que /etc/environment aceita apenas atribuições de variáveis (sem sintaxe de shell).

# /etc/profile.d/myapp.sh
export PATH="/opt/myapp/bin:$PATH"

5. Não Encontra com sudo / cron

Conclusão: sudo usa secure_path e cron um PATH mínimo; use caminhos completos ou defina o PATH.

5-1. command not found com sudo

sudo sobrescreve o PATH com secure_path do /etc/sudoers.

$ sudo -V | grep -i path
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Correções:

# (1) Use o caminho completo (mais confiavel)
$ sudo /home/user/.local/bin/myscript

# (2) Transporte o ambiente com sudo -E (pode ser ignorado quando secure_path esta definido)
$ sudo -E env "PATH=$PATH" myscript

# (3) Correcao permanente: edite secure_path com visudo
$ sudo visudo
# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/user/.local/bin"

secure_path existe para prevenir ataques de injeção de PATH durante escalonamento de privilégios. Não amplie descuidadamente -- adicione apenas os diretórios que realmente precisa.

5-2. command not found no cron

O cron inicia com um PATH mínimo.

$ env -i sh -c 'echo $PATH'
/usr/bin:/bin

Correções (em ordem de preferência):

# (1) Declare PATH no topo do crontab
PATH=/usr/local/bin:/usr/bin:/bin:/home/user/.local/bin
* * * * * myscript

# (2) Use caminhos absolutos no script
* * * * * /home/user/.local/bin/myscript

70% dos problemas do cron são PATH. O segundo maior problema é stdout/stderr não redirecionados. Sempre adicione >> /tmp/cron.log 2>&1 para poder ver o que está acontecendo.

6. Template de Diagnóstico para Copiar e Colar

Conclusão: Um template para copiar e colar que executa verificação, PATH, hash, busca de pacote e checagens do sudo.

# 1. Verificar existencia
command -v ansible

# 2. Mostrar PATH
echo $PATH

# 3. Limpar hash (a correcao padrao logo apos instalar)
hash -r
command -v ansible

# 4. Buscar o pacote
apt-cache search ^ansible$       # Debian / Ubuntu
dnf provides '*/ansible'         # RHEL / Fedora

# 5. Verificar com sudo
sudo command -v ansible
sudo -V | grep -i path

Coisas que você nunca deve fazer

  • Sobrescrever PATH atribuindo PATH= sem valor existente
  • Colocar o mesmo export de PATH tanto em ~/.bash_profile quanto em ~/.profile (um será ignorado)
  • Executar chmod 777 reflexivamente quando o sudo falha

Próximas Leituras