O script Shell funciona quando salvo com o nano, mas não quando salvo com o Notepad ++

O script Shell funciona quando salvo com o nano, mas não quando salvo com o Notepad ++

Quando copio meu script bash do Notepad ++ para um novo arquivo com o editor nano dentro do SSH e salvo. Funciona bem. (sh./instalar).

Mas se eu salvar o arquivo (exatamente o mesmo conteúdo), fazer upload para meu servidor web, baixá-lo usando Wget na mesma máquina. Recebo erros de sintaxe. Eu verifiquei a codificação e eles parecem ser os mesmos. Desde então, usei uma infinidade de codificação de caracteres para ver se isso resolveria o problema. Também estou configurando o arquivo como executável depois de baixá-lo usando o wget!

O arquivo funciona bem e não tenho nenhum erro ao copiar e colar usando o nano. Alguma ideia do que isso pode ser?

Responder1

Eu estaria disposto a apostar que o problema está relacionado aos finais de linha. Você provavelmente está passando por uma máquina não-*nix em algum lugar ao longo do caminho. Também tive um problema uma vez em que apache(executando no Linux) estava adicionando finais de linha no estilo do Windows aos arquivos de texto carregados, então você pode ver algo semelhante.

Para testar, pegue o arquivo que você baixou e passe-o od. Se for um arquivo longo, basta pegar as primeiras linhas:

head script.sh | od -c

Dê uma olhada na saída e verifique se você tem algo parecido com isto:

f   o   o  \r  \n

É \rum retorno de carro e no Windows as linhas terminam com \r\nem vez de \n*nix. Se descobrir que esse era realmente o problema, você pode corrigir seu arquivo removendo os retornos de carro:

sed -i 's/\r//g' script.sh

Responder2

Como @graeme apontou astutamente, já que você tem o script em ambos os formatos no servidor, você pode executar uma tarefa simples diffpara determinar o que há de diferente entre a versão funcional e a versão problemática.

$ diff working.sh broken.sh

Você também pode fazer uma comparação lado a lado como esta:

$ diff -y working.sh broken.sh

Se o script não estiver funcionando devido a algum tipo de erro de digitação, muitas vezes você poderá detectá-los adicionando a -xopção a bash, o que o torna detalhado.

$ bash -x broken.sh

Você também pode incorporar essa opção ao shebang ( #!/bin/bash) na parte superior de seus scripts, assim:

#!/bin/bash -x

Finais de linha

Esse é frequentemente o problema ao mover arquivos do Windows para sistemas Unix/Linux. A questão tem a ver com a forma como os finais das linhas são indicados nas 2 plataformas. Você pode ler mais sobre isso aqui na Wikipedia, intitulado:Novas linhas.

faça um arquivo de amostra

$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt

Como @terdon descreveu em sua resposta, você pode usar sedpara removê-los, mas também pode usar uma ferramenta chamada dos2unixpara fazer a mesma coisa. Você pode usá-lo de duas maneiras:

$ dos2unix unixfile.txt

ou se você não quiser sobrescrever o arquivo existente:

$ dos2unix -n oldfile.txt newfile.txt

Ao usar o que diffmencionei anteriormente, você obterá uma saída como esta ao comparar esses 2 arquivos:

$ diff -y unixfile.txt winfile.txt 
This is a couple                            |   This is a couple
of lines of sample                          |   of lines of sample
text.                                       |   text.

Você não será capaz de discernir as diferenças, apenas que elas estão lá. Novamente, a resposta de @terdon mostra um método para solucionar o problema usando od. É claro que você pode usar várias maneiras de descobrir o que está acontecendo.

Usando vim

com o filecmd.

$ file unixfile.txt
winfile.txt: ASCII text 

$ file winfile.txt 
unixfile.txt: ASCII text, with CRLF line terminators

O texto acima destaca o problema de que o arquivo do Windows possui CRLF (também conhecido como Carriage Return + Linefeed caracteres no final das linhas). Esses caracteres são 0x0D e 0x0A em hexadecimal, veja novamente oArtigo da Wikipedia sobre novas linhasse você quiser saber mais sobre isso.

Você também pode usar vimpara ver o problema:

$ vim winfile.txt

Aqui está uma pequena sequência que mostra o que fazer vimpara ver o problema. Os caracteres CRLF normalmente aparecem no Unix como ^M, isso é Ctrl+ M.

                                       ss do vim

A sequência me mostra reabrindo o arquivo, winfile.txtcomo um arquivo Unix formatado ( :e ++ff=unix). Isso informa vimpara não detectar automaticamente que o arquivo está formatado para Windows e, portanto, exibirá os ^Mcaracteres de terminação de linha.

informação relacionada