Anúncios incomodam? Ir Sem anúncios Hoje

CRLF versus LF O Erro de Final de Linha que Quebra o CI

Publicado em

Seu script de shell funciona localmente, mas o CI lança 'interprete inválido: /bin/bash^M'. Este é o problema de terminação de linha CRLF. Aprenda o que o causa, como detectá-lo e como corrigi-lo permanentemente com .gitattributes.

CRLF vs LF: O Erro de Quebra de Linha que Quebra o CI 1
ANUNCIADO Remover?

Seu script de shell executa perfeitamente no seu laptop. Você o pusha para o GitHub. O CI falha com um erro obscuro /bin/bash^M: bad interpreter Você acabou sendo mordido pela maior bug invisível no desenvolvimento de software: os terminadores de linha errados.

Este guia explica o que CRLF e LF realmente são, por que misturar os dois corrompe silenciosamente scripts e configurações, e os passos exatos para prevenir que erros de terminador de linha nunca cheguem ao seu pipeline novamente.

O que são CRLF e LF?

Todo arquivo de texto precisa de uma forma de marcar o final de uma linha. Duas convenções existem, herdadas da era das máquinas de telegrafia físicas:

  • LF (Line Feed) — um caractere (byte \n ). Usado por Linux, macOS e todos os sistemas derivados do Unix. 0x0ACRLF (Carriage Return + Line Feed)
  • — dois caracteres, (bytes \r\n ). Usado por Windows e MS-DOS. 0x0D 0x0AOs nomes vêm da mecânica de máquinas de escrever. Um

carriage return movia a cabeça de impressão de volta ao início da linha. Um line feed avaliava o papel uma linha. Windows mantinha os dois; Unix eliminou o carro de retorno redundante. Por que CRLF quebra pipelines de CI?

Em Linux (onde praticamente todos os executadores de CI operam), o

não é espaço em branco — é um caractere literal. Quando um script de shell é salvo com terminadores CRLF, cada linha termina com \r antes da quebra de linha. O kernel interpreta a linha de início como \r e procura por um binário literal chamado #!/bin/bash\r . Esse binário não existe. bash\rO erro resultante parece assim:

é a forma como terminais exibem o caractere de retorno de carro. Ele é invisível na maioria dos editores de texto, o que torna esse bug tão desorientador.

: bad interpreter: /bin/bash^M: No such file or directory

O ^M Outros locais onde CRLF causa danos silenciosamente

Dockerfiles

  • — Uma instrução com terminadores CRLF injeta em cada comando, quebrando comparações de strings e caminhos de arquivos. RUN Scripts em Python \r quando
  • é seguida porSyntaxError: unexpected character after line continuation character arquivos .env \ — Os valores das variáveis de ambiente adquirem um caractere de retorno final, \r\n.
  • não corresponde ao esperado arquivos CSV e de dados \r— Analisadores que leem linha por linha podem incluir APP_ENV=production\r no último campo de cada linha. production.
  • Chaves autorizadas SSH — Um arquivo de chave com terminadores CRLF será rejeitado silenciosamente pelo servidor SSH. \r Diferenças Git
  • — Cada linha parece alterada, escondendo mudanças reais sob ruído. Como detectar problemas com terminadores de linha
  • A maioria dos editores oculta terminadores de linha por padrão. Aqui estão métodos confiáveis para verificar: Usando cat ou hexdump

Usando o comando file

Usando grep

Como corrigir terminadores de linha CRLF

# Show ^M characters
cat -A yourfile.sh | head -5

# Hex dump to see 0x0d (CR) characters
hexdump -C yourfile.sh | head -10

Opção 1: dos2unix (correção rápida e única)

file yourfile.sh
# CRLF output: yourfile.sh: ASCII text, with CRLF line terminators
# LF output:   yourfile.sh: ASCII text

remove os retornos de carro dos arquivos. Está disponível em todas as principais distribuições Linux:

# Returns exit code 0 (found) if CRLF endings exist
grep -rlP "\r" . --include="*.sh" --include="*.py" --include="*.yml"

Opção 2: sed (sem necessidade de ferramentas adicionais)

Opção 3: Corrigir no VS Code ou JetBrains

dos2unix No VS Code, o modo de terminador de linha é exibido na barra de status (canto inferior direito). Clique para alternar entre CRLF e LF para o arquivo atual. Para alterar o padrão para novos arquivos, defina

# Fix a single file
dos2unix yourscript.sh

# Fix all shell scripts recursively
find . -name "*.sh" -exec dos2unix {} \;

# Reverse: convert LF to CRLF (unix2dos)
unix2dos yourfile.sh

no seu

# Remove carriage returns in-place
sed -i 's/\r//' yourscript.sh

# Or using tr
tr -d '\r' < input.sh > output.sh

No IDEs JetBrains, vá para

Arquivo → Separadores de Linha "files.eol": "\n" para alterar o arquivo atual, ou defina o padrão em settings.json.

Editor → Estilo de Código → Separador de Linha A Correta Solução: .gitattributes Correções pontuais não escalam. A solução correta é um arquivo que informa ao Git quais terminadores de linha devem ser exigidos, independentemente do editor ou do sistema usado pelos contribuidores..

Após adicionar esse arquivo, execute o seguinte para re-normalizar todo o repositório de uma vez:

A configuração autocrlf do Git — e por que ela muitas vezes piora as coisas .gitattributes O Git tem uma configuração que tenta converter automaticamente os terminadores de linha:

# .gitattributes — commit this to the root of your repository

# Default: normalize all text files to LF in the repo
* text=auto eol=lf

# Explicitly enforce LF for scripts and configs
*.sh    text eol=lf
*.bash  text eol=lf
*.py    text eol=lf
*.rb    text eol=lf
*.yml   text eol=lf
*.yaml  text eol=lf
*.json  text eol=lf
*.env   text eol=lf
Dockerfile text eol=lf
Makefile   text eol=lf

# Windows-only files can keep CRLF
*.bat  text eol=crlf
*.cmd  text eol=crlf
*.ps1  text eol=crlf

# Binary files — never touch line endings
*.png  binary
*.jpg  binary
*.gif  binary
*.zip  binary
*.pdf  binary

— converte LF para CRLF em checkout (Windows), CRLF para LF em commit. Intendida para usuários do Windows.

git add --renormalize .
git commit -m "chore: normalize line endings via .gitattributes"

— converte CRLF para LF em commit, não faz nada em checkout. Mais segura para Mac/Linux.

— O Git não faz nada. O que o editor salva é o que é commitado. core.autocrlf O problema:

  • core.autocrlf=true é uma configuração local armazenada em
  • core.autocrlf=input . Cada desenvolvedor da equipe tem um valor diferente, então os commits de máquinas diferentes produzem terminadores de linha diferentes. Isso cria ruído constante nas diferenças e falhas intermitentes no CI dependendo de quem ultimamente tocou em um arquivo.
  • core.autocrlf=false Regra geral:

use core.autocrlf para definir a política de terminadores de linha no repositório. Deixe ser o que cada desenvolvedor tem — sobrescreve isso. ~/.gitconfigAdicionando uma verificação no CI

Mesmo com em lugar, vale a pena adicionar uma verificação explícita no CI para capturar quaisquer arquivos que passarem. Um passo de duas linhas cobre a maioria dos casos: .gitattributes Este passo falha de forma clara na fonte — a solicitação — em vez de falhar silenciosamente na implantação. core.autocrlf Referência rápida: CRLF versus LF .gitattributes LF (

CRLF (

Bytes .gitattributes Usado por

# In your CI workflow (GitHub Actions example)
- name: Check for CRLF line endings
  run: |
    if grep -rlP "\r" . --include="*.sh" --include="*.py" --include="*.yml" --include="Dockerfile"; then
      echo "ERROR: CRLF line endings found. Run dos2unix on the above files."
      exit 1
    fi

Linux, macOS, Unix

Windows, MS-DOS

Seguro para scripts de shell\n)Não — quebra a linha de início\r\n)
Seguro para Dockerfile0x0A0x0D 0x0A
Seguro para arquivos .envNão — adiciona \r ao final dos valoresRecomendação do Git
Normalizar para LF no repositórioSimApenas para arquivos .bat/.cmd/.ps1
CRLF versus LF: O Erro de Terminador de Linha que Quebra o CI 2SimNão
CRLF versus LF: O Erro de Terminador de Linha que Quebra o CI 1SimNão — adiciona \r no final dos valores
Recomendação do GitNormalizar para LF no repositórioApenas para .bat/.cmd/.ps1
Quer eliminar anúncios? Fique sem anúncios hoje mesmo

Instale nossas extensões

Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida

Ao Extensão do Chrome Ao Extensão de Borda Ao Extensão Firefox Ao Extensão Opera

O placar chegou!

Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!

ANUNCIADO Remover?
ANUNCIADO Remover?
ANUNCIADO Remover?

Notícias com destaques técnicos

Envolver-se

Ajude-nos a continuar fornecendo ferramentas gratuitas valiosas

Compre-me um café
ANUNCIADO Remover?