"command not found" para seus próprios scripts - PATH e chmod
O que você vai aprender
- Por que apenas o seu script diz
command not found - Como diferenciar
command not founddePermission denied - Como seguir na ordem
./,chmod +x, PATH ehash -r
Resumo rápido
command not found significa que o shell não encontrou esse comando no seu PATH. Para seus próprios scripts, corrija nesta ordem:
- Execute do diretório atual com
./script.sh(um nome simples só busca no PATH) - Adicione o bit de execução com
chmod +x script.sh - Adicione o diretório ao PATH para uso diário (
~/binou~/.local/bin) - Limpe o cache de caminhos com
hash -rapós mover ou substituir o script
Premissas
- Shell: bash (o padrão no Ubuntu / Debian)
- Alvo: um script
.shque você escreveu, ou um comando que você compilou - zsh funciona da mesma forma; apenas detalhes como
hash -rdiferem
Por que apenas o meu script diz command not found?
Conclusão: O bash busca um nome de comando simples apenas nos diretórios listados no PATH. O diretório atual não está no PATH por padrão, então digitar
script.shnão encontra nada.
Quando você digita script.sh, o bash resolve na seguinte ordem:
- Funções do shell, aliases e builtins
- Caminhos já em cache no
hash - Os diretórios listados na variável de ambiente
PATH(do início ao fim)
Se script.sh não está em nenhum dos diretórios do PATH, você recebe command not found mesmo que o arquivo esteja bem na sua frente.
$ ls script.sh $ script.sh bash: script.sh: command not found
Deixar o diretório atual (.) fora do PATH é um padrão de segurança deliberado. Se . estivesse no início do PATH, um atacante poderia colocar um arquivo malicioso com nome de um comando real (ls) em um diretório onde você faz cd, e você o executaria por acidente. Por isso um script "bem aqui" precisa ser nomeado explicitamente.
Qual a diferença entre command not found e Permission denied?
Conclusão:
command not foundsignifica "não localizado";Permission deniedsignifica "localizado, mas sem permissão de execução." A mensagem indica qual caminho seguir.
Esses dois erros têm causas e correções diferentes.
| Mensagem | Significado | Correção principal |
|---|---|---|
command not found |
Comando não encontrado no PATH | Usar ./ / adicionar ao PATH |
Permission denied |
Arquivo existe mas sem bit de execução | chmod +x |
bad interpreter |
Caminho shebang errado / terminações CRLF | Corrigir shebang / dos2unix |
# O caminho esta certo, mas nao ha permissao de execucao $ ./script.sh bash: ./script.sh: Permission denied
Se adicionar ./ muda o erro para Permission denied, o problema de PATH está resolvido e a próxima questão são permissões. Se você vê bad interpreter, o shebang ou terminações de linha estão com problema, então leia Corrigindo "bad interpreter".
Execute com ./ primeiro
Conclusão: Execute um script no diretório atual com
./script.sh. O./é um caminho explícito que pula a busca no PATH.
# NG: apenas o PATH e buscado, entao nao e encontrado $ script.sh bash: script.sh: command not found # OK: nomeie o arquivo no diretorio atual diretamente $ ./script.sh Hello
Se está em outro lugar, use um caminho absoluto ou relativo.
$ /home/alice/tools/script.sh $ ~/tools/script.sh $ bash script.sh # passar ao bash funciona mesmo sem o bit de execucao
Passar o script para um interpretador (bash script.sh) o executa mesmo sem permissão de execução. Isso é útil para separar temporariamente um "problema de PATH" de um "problema de permissão."
O que acontece sem permissão de execução?
Conclusão: Sem o bit de execução,
./script.shpara comPermission denied. Conceda comchmod +x.
Scripts recem-criados, baixados ou copiados frequentemente perdem a permissão de execução.
$ ls -l script.sh -rw-r--r-- 1 alice alice 42 Jun 6 10:00 script.sh $ ./script.sh bash: ./script.sh: Permission denied
-rw-r--r-- não tem x (bit de execução). Adicione.
$ chmod +x script.sh $ ls -l script.sh -rwxr-xr-x 1 alice alice 42 Jun 6 10:00 script.sh $ ./script.sh Hello
chmod 777 é desnecessário e perigoso. Se você só precisa executar o arquivo, chmod +x (ou chmod 755) é suficiente. Torná-lo gravável por todos com 777 é um risco de segurança.
Como adicionar meu diretório ao PATH?
Conclusão: Para evitar digitar
./toda vez, adicione o diretório do seu script aoPATH. Coloqueexport PATHno~/.bashrcpara tornar permanente.
Primeiro, verifique o PATH atual.
$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
Adicione o diretório onde você guarda seus scripts (por exemplo ~/bin).
# Apenas para esta sessao (shell atual) $ export PATH="$HOME/bin:$PATH"
Para tornar permanente, adicione ao final de ~/.bashrc (ou ~/.profile para login shells).
# Adicionar ao final de ~/.bashrc export PATH="$HOME/bin:$PATH"
# Recarregar no shell atual $ source ~/.bashrc $ which script.sh /home/alice/bin/script.sh $ script.sh # executa sem ./ Hello
~/bin e ~/.local/bin
O ~/.profile padrão do Ubuntu adiciona ~/bin e ~/.local/bin ao PATH no login se eles existirem. Coloque seus scripts em qualquer um dos dois e o PATH geralmente funciona sem configuração extra (pode ser necessário fazer login novamente para que tenha efeito).
Entradas do PATH são separadas por :, e a posição define a prioridade. Com $HOME/bin:$PATH seu script vence; com $PATH:$HOME/bin comandos existentes vencem. Para evitar sobrescrever acidentalmente um comando do sistema com o mesmo nome, adicione no final.
Ainda não encontra, ou pega o binário antigo?
Conclusão: O bash armazena em cache o caminho de um comando uma vez que o encontra (
hash). Logo após mover ou substituir um script, ele pode usar o caminho antigo. Limpe o cache comhash -r.
Quando PATH e permissões parecem corretos mas o comportamento está errado, use type para ver o que o bash realmente pretende executar e de onde.
$ type -a script.sh script.sh is /home/alice/bin/script.sh
Se type aponta para um local antigo, ou um comando que você excluiu ainda executa, o cache está desatualizado.
# Limpar caminhos de comandos em cache $ hash -r # Verificar novamente $ type -a script.sh
which busca no PATH no sistema de arquivos, mas type reporta como o bash realmente resolve o nome, incluindo aliases, funções, builtins e o cache hash. Para diagnóstico, type -a é a escolha confiável.