O shell script do Bash / Korn editado no Windows gera o erro '… ^ M: não encontrado'

7

Algumas informações sobre o assunto:

Sou novo em scripts e escrevi um script Bash simples no Windows usando o Notepad ++.

cxStopAllServicesOnSERVER.sh

#!/usr/bin/bash
cd "/some/path"
echo "Hi. Logs can be found at "'pwd'"/cxStartStopLogger.log"
echo "["'date'"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"
exit

Agora, depois de carregá-lo e definir as permissões de arquivo necessárias, tentei executá-lo da seguinte maneira:

bash-3.00$ cat cxStopAllServicesOnSERVER.sh #Let's have a look at the code.
#!/usr/bin/bash
cd "/some/path/"
echo "Hi. Logs can be found at "'pwd'"/cxStartStopLogger.log"
echo "["'date'"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"

bash-3.00$ # Code and hashbang 'looks' correct, 
bash-3.00$ # if there is any issue with the format (EOL characters and such) 
bash-3.00$ # we cannot see it using cat.
bash-3.00$ 
bash-3.00$ sh cxStopAllServicesOnSERVER.sh
cxStopAllServicesOnSERVER.sh[2]: /some/path^M:  not found
Hi. Logs can be found at /some/path/cxStartStopLogger.log
bash-3.00$ # Note that ^M appears at the end of the line.

bash-3.00$ bash -x cxStopAllServicesOnSERVER.sh
+ cd $'/some/path\r'
: No such file or directory1.sh: line 2: cd: /some/path
++ pwd
' echo 'Hi. Logs can be found at /some/path/cxStartStopLogger.log
Hi. Logs can be found at /some/path/cxStartStopLogger.log
++ date
+ echo '[Sun' Nov 18 00:28:17 EST '2012]*** STOPPING ALL SERVICES ON SERVER ***'
bash-3.00$ # Note that '\r' return character appears at the end of the line.

Problema: Quando eu mudo o código para o shell korn, enfrento o mesmo problema. Aparece que um caractere incorreto está sendo adicionado no final da linha.

NOTA: Eu encontrei a solução e postei o mesmo como resposta. Sinta-se à vontade para atualizá-lo ou melhorá-lo para ajudar outros iniciantes que possam enfrentar o mesmo problema. Obrigado!

    
por Kent Pawar 18.11.2012 / 06:45

2 respostas

14

Depois de bisbilhotar vários fóruns e alguma postagem sobre estouro de pilha, encontrei o problema.

Aqui está uma explicação para entender melhor e "ver" a causa raiz dos erros.

First off if you are writing code on Windows, better arm yourself with Notepad++. It's basically the Swiss Army knife of text-editors in my opinion.

Agora, para ver os caracteres EOL (fim de linha) e outros símbolos de controle, faça o seguinte:

1.Abra o arquivo no Notepad ++.

Select View > Show Symbol > Show All Characters from the Menu bar

You should now see the symbols as follows: Screenshot of Notepad++:Editing a UNIX script on Windows

Aha! Windows/MS-DOS uses CR+LF to indicate end-of-lines. Now UNIX uses LF character to indicate line termination (EOL character).

2.1.Vamos converter o Windows EOL em EOLs do UNIX:

Selecione EDITAR > Conversão EOL > Formato UNIX

Você deve ver algo assim:

Issoexplicaporquevimosocaractere'\r'sendoanexadonofinaldalinha.IssoocorreporqueoUNIXreconheceuo'\n'ouLF(linefeed)comoocaracteredeterminaçãodelinha/EOL,masignorouocaractere'\r'ou^M(retornodecarro).

TambémpodemostestaroproblemadeEOLpor

bash-3.00$headmyScript.sh|cat-vet|head-1#usr/bin/bash^M$bash-3.00$#Weseethat^M,thatis\risfoundattheendofeachline.

2.2.SevocêgostariadeconverteroarquivodoWindowsparaoformatoUNIXEOLnoUNIX,entãoháduasmaneirasdecorrigirisso:

$dos2unixmyScript.sh

ou

Useasoluçãofornecidapelo@ChrisDownconformeabaixo:

$sed-i's/\r$//'myScript.sh

Referências:

  1. Paramaisinformaçõessobrealinha rescisão e O que é a diferença entre r e n referencie esses links.
por 18.11.2012 / 07:22
4

Seu script contém finais de linha CRLF, enquanto o Unix usa finais de linha LF. O seguinte irá removê-los, se você tiver o GNU sed :

sed -i 's/\r$//' cxStopAllServicesOnSERVER.sh

Se você não tiver o GNU sed , escreva em um arquivo temporário e mova-o por cima do arquivo antigo.

Como um aparte, se você invocar um script usando sh , você irá sobrescrever o shebang. Isso provavelmente não é o que você quer.

    
por 18.11.2012 / 06:50