Corrigindo "bad interpreter" - Problemas de Shebang e CRLF
O que é o erro "bad interpreter"?
Conclusão: O shell não consegue executar o interpretador indicado na linha shebang do script. Quase todos os casos são terminações de linha CRLF ou um caminho shebang errado.
Você tenta executar um shell script e encontra um erro como este:
$ ./deploy.sh -bash: ./deploy.sh: cannot execute: required file not found
O arquivo existe e tem permissão de execução, mas se recusa a rodar. Este erro significa que o kernel não consegue iniciar o interpretador declarado na linha 1 (o #!... shebang).
A mensagem acima é o que o bash 5.1 e posteriores exibem (Ubuntu 22.04+, Debian 11+, RHEL 9+, etc.). No bash 5.0 e anteriores (Ubuntu 20.04, Debian 10, RHEL 8, etc.) você vê o caminho do interpretador e um ^M (CR), como -bash: ./deploy.sh: /bin/bash^M: bad interpreter: No such file or directory. A causa é idêntica em ambos os casos.
Reduza a duas causas primeiro
Quase sempre é uma de duas coisas:
- Terminações de linha CRLF se infiltraram (mais comum)
- O caminho do shebang não existe
No bash 5.1 e posteriores ambas produzem o mesmo cannot execute: required file not found, então o texto do erro sozinho não consegue diferenciá-las. Não confie na mensagem; observe o arquivo diretamente com file e cat -A (abaixo) para decidir.
Note que Permission denied é um problema diferente: falta do bit de execução (chmod +x). É fácil confundir os dois, então para o lado da permissão veja Corrigindo Permission denied.
Por que diz que não encontra o interpretador?
Conclusão: O kernel usa a linha shebang literalmente como caminho do interpretador. Um
\rfinal do CRLF transforma/bin/bashem/bin/bash\r, um caminho que não existe. O bash 5.1 e posteriores reportam comocannot execute: required file not found; o bash 5.0 e anteriores reportam comoNo such file or directory.
O kernel Linux lê a primeira linha começando com #! e trata o texto após #! literalmente, como o caminho absoluto para um interpretador. Essa é a raiz do erro.
Arquivos salvos no Windows ou por alguns editores usam terminações de linha CRLF (\r\n) em vez de LF (\n). A linha shebang é então lida como:
#!/bin/bash\r
este \r (CR) faz parte do "caminho"
Então o kernel procura um arquivo literalmente chamado /bin/bash + retorno de carro. Esse arquivo não existe, então falha. O bash 5.1 e posteriores exibem cannot execute: required file not found; o bash 5.0 e anteriores exibem No such file or directory e mostram o CR como ^M (o ^M só aparece na mensagem do bash 5.0 e anteriores).
Mesmo quando o nome e o caminho estão corretos, um único \r invisível quebra tudo. Por isso a linha "parece certa mas não roda."
O caminho do shebang em si também pode estar errado. Por exemplo, você escreveu #!/usr/local/bin/python3 mas o Python só existe em /usr/bin/python3 naquela máquina.
Como saber se CRLF é a causa?
Conclusão: Use
filepara detectar o tipo de terminação de linha ecat -Apara revelar^Mno final das linhas. Ambos expõe CRLF rapidamente.
Observe a causa antes de corrigir qualquer coisa.
Verificar terminações de linha com file
$ file deploy.sh
Quando CRLF está presente, você vê:
deploy.sh: Bourne-Again shell script, ASCII text executable, with CRLF line terminators
with CRLF line terminators confirma que terminações de linha são a causa. Um arquivo limpo mostra apenas ASCII text executable sem nota de CRLF.
Revelar finais de linha com cat -A
$ cat -A deploy.sh | head -3
#!/bin/bash^M$ ^M$ echo "deploy start"^M$
cat -A marca finais de linha com $ e CR com ^M. Se toda linha termina com ^M$, é CRLF. Um arquivo limpo mostra apenas $.
Inspecionar a linha shebang com precisão
$ head -1 deploy.sh | od -c
0000000 # ! / b i n / b a s h \r \n
\r \n juntos significa CRLF. \n sozinho significa LF (limpo).
Como corrigir terminações de linha CRLF?
Conclusão:
dos2unixé a correção mais confiável. Sem ele, usesed -i 's/\r$//'para remover o CR final de cada linha, depois re-verifique comfile.
Opção 1: dos2unix (recomendado)
$ dos2unix deploy.sh
dos2unix: converting file deploy.sh to Unix format...
Uma ferramenta dedicada que converte CRLF para LF. Instale com sudo apt install dos2unix no Ubuntu/Debian ou sudo dnf install dos2unix em sistemas baseados em RHEL.
Opção 2: sed (sem instalação extra)
Se dos2unix não estiver disponível, sed resolve.
$ sed -i 's/\r$//' deploy.sh
s/\r$// significa "excluir o CR no final de cada linha." -i edita o arquivo in-place. Use -i.bak para manter um backup por precaução.
$ sed -i.bak 's/\r$//' deploy.sh # mantem deploy.sh.bak
Com tr -d '\r', tr só lê da entrada padrão, então você não pode redirecionar de volta para o mesmo arquivo (ele ficaria vazio). Sempre escreva em um arquivo diferente.
$ tr -d '\r' < deploy.sh > deploy.unix.sh # OK $ tr -d '\r' < deploy.sh > deploy.sh # ERRADO: acaba vazio
Opção 3: converter no vim
Se o arquivo já está aberto em um editor, corrija in-place.
:set fileformat=unix :w
Sempre confirme a correção
$ file deploy.sh deploy.sh: Bourne-Again shell script, ASCII text executable $ ./deploy.sh deploy start
Se a nota CRLF line terminators desapareceu, está feito.
Como corrigir um caminho shebang errado?
Conclusão: Confirme que o interpretador realmente existe no caminho do shebang com
which. Para portabilidade, use#!/usr/bin/env bash.
Este é o caso em que nenhum interpretador existe no caminho do shebang. No bash 5.0 e anteriores a mensagem mostra o caminho problemático, como bash: ./run.sh: /usr/local/bin/python3: bad interpreter. No bash 5.1 e posteriores um caminho ausente e CRLF parecem idênticos -- ambos exibem cannot execute: required file not found sem mostrar o caminho. Em ambas as versões, não confie no texto do erro: descarte CRLF com file / cat -A, depois confirme se o interpretador existe com which.
Confirme que o interpretador existe
$ head -1 run.sh #!/usr/local/bin/python3 $ which python3 /usr/bin/python3
O shebang aponta para /usr/local/bin/python3, mas o binário real está em /usr/bin/python3. Os caminhos divergem.
Resolva com env
Em vez de fixar o caminho real, deixe env encontrar o interpretador no PATH para melhor portabilidade.
#!/usr/bin/env python3
#!/usr/bin/env bash
env busca o interpretador no PATH, então o script funciona independente de o binário estar em /usr/bin ou /usr/local/bin. É a forma moderna e resiliente ao ambiente.
Note que passar argumentos para o interpretador através de env é limitado (sistemas mais antigos não suportam múltiplos argumentos). Opções como set -euo pipefail pertencem ao corpo do script, não ao shebang.
Como evitar que volte a acontecer?
Conclusão: Fixe arquivos
.shcomo LF com.gitattributese configure seu editor para salvar como LF. Esses dois passos bloqueiam quase toda reintrodução de CRLF.
Corrigir uma vez é inútil se CRLF volta a cada save ou commit. Corte na origem.
Fixar terminações de linha no Git
Coloque um .gitattributes na raiz do repositório e fixe shell scripts como LF.
*.sh text eol=lf
Agora checkouts sempre usam LF, então o arquivo sobrevive a edições de máquinas Windows.
Verifique também sua configuração de core.autocrlf. No Linux/macOS, input é a escolha segura.
$ git config --global core.autocrlf input
core.autocrlf=true é comum entre desenvolvedores Windows, mas adiciona CRLF no checkout, criando condições para bad interpreter em shell scripts. Ao trabalhar com scripts, sobreponha explicitamente com eol=lf no .gitattributes.
Configure seu editor para salvar como LF
- VS Code: clique no indicador
CRLFno canto inferior direito e troque paraLF. Adicione um.editorconfigcomend_of_line = lfpara automatizar - vim: salve com
:set fileformat=unix - Windows Notepad: não use para shell scripts (tende a adicionar CRLF)
Checklist final
file script.shnão mostraCRLF line terminators- O caminho do shebang em
head -1 script.shresolve para um interpretador real viawhich ls -l script.shmostra o bit de execução (x) ativo
Com os três em ordem, bad interpreter não retornará.