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

4

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

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

O arquivo é executado corretamente e eu tenho zero erros ao copiar e colar usando o nano. Alguma idéia do que isso possa ser?

    
por user3185938 05.03.2014 / 01:42

2 respostas

8

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 da linha. Também corri para um problema em que apache (rodando no Linux) estava adicionando terminações de linha no estilo windows aos arquivos de texto enviados, então você pode estar vendo algo similar.

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

head script.sh | od -c

Examine a saída e verifique se você tem algo assim:

f   o   o  \r  \n

O \r é um retorno de carro e, no Windows, as linhas são finalizadas com \r\n , em oposição a \n on * nix. Se acontecer de que esse era realmente o problema, você pode corrigir seu arquivo removendo os retornos de carro:

sed -i 's/\r//g' script.sh
    
por 05.03.2014 / 03:31
4

Como @graeme apontou astutamente desde que você tem o script em ambos os formulários no servidor, você pode executar um simples diff para determinar o que é diferente entre a versão de trabalho e a versão problemática.

$ diff working.sh broken.sh

Você também pode fazer um diff lado a lado assim:

$ 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 opção -x a bash , o que faz com que seja detalhado.

$ bash -x broken.sh

Você também pode incorporar essa opção no shebang ( #!/bin/bash ) na parte superior de seus scripts da seguinte forma:

#!/bin/bash -x

Endings de linha

Este é frequentemente o problema ao mover arquivos do Windows para sistemas Unix / Linux. A questão tem a ver com como as extremidades das linhas são indicadas nas duas plataformas. Você pode ler mais sobre isso aqui na Wikipedia, intitulado: Newlines .

faça um arquivo de exemplo

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

Como @terdon descreveu em sua resposta, você pode usar sed para removê-los, você também pode usar uma ferramenta chamada dos2unix para fazer a mesma coisa também. 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

Quando você usa o diff acima que mencionei anteriormente, você obterá uma saída assim quando comparar esses dois 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 encaminhar o problema usando od . É claro que você pode usar várias maneiras de descobrir o que está acontecendo.

Usando o vim

com o file cmd.

$ file unixfile.txt
winfile.txt: ASCII text 

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

O texto acima está destacando o problema, que o arquivo do Windows tem caracteres CRLF (também conhecidos como Carriage Return + Linefeed no final das linhas). Esses caracteres são 0x0D & 0x0A em hexadecimal, veja novamente o artigo da Wikipédia sobre Newlines se você quiser saber mais sobre isso.

Você também pode usar vim para ver o problema também:

$ vim winfile.txt

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

A sequência está me mostrando a reabertura do arquivo, winfile.txt como um arquivo Unix formatado ( :e ++ff=unix ). Isso diz a vim para não detectar automaticamente que o arquivo está formatado para o Windows e, portanto, exibirá os caracteres de término de linha ^M .

    
por 05.03.2014 / 02:21