El script de Shell funciona cuando se guarda con nano pero no cuando se guarda con Notepad++

El script de Shell funciona cuando se guarda con nano pero no cuando se guarda con Notepad++

Cuando copio mi script bash desde Notepad ++ en un nuevo archivo con nano editor dentro de SSH y lo guardo. Funciona bien. (sh ./instalar).

Pero si guardo el archivo (exactamente el mismo contenido), lo subo a mi servidor web y lo descargo usando Wget en la misma máquina. Recibo errores de sintaxis. Revisé la codificación y parecen ser iguales. Desde entonces, he utilizado una gran cantidad de codificación de caracteres para ver si resuelve el problema. ¡También configuraré el archivo como ejecutable una vez que lo descargue usando wget!

El archivo funciona bien y no tengo errores al copiar y pegar usando nano. ¿Alguna idea de qué puede ser esto?

Respuesta1

Estaría dispuesto a apostar que el problema está relacionado con los finales de línea. Probablemente estés pasando por una máquina que no es *nix en algún momento. También me encontré con un problema una vez en el que apache(ejecutando en Linux) agregaba finales de línea de estilo Windows a los archivos de texto cargados, por lo que es posible que veas algo similar.

Para probar, tome el archivo que descargó y páselo od. Si es un archivo largo, simplemente tome las primeras líneas:

head script.sh | od -c

Mire el resultado y verifique si tiene algo como esto:

f   o   o  \r  \n

Es \run retorno de carro y en Windows, las líneas terminan en *nix, \r\nen lugar de \nen *nix. Si resulta que este era realmente el problema, puedes arreglar tu archivo eliminando los retornos de carro:

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

Respuesta2

Como @graeme ha señalado astutamente, dado que tiene el script en ambas formas en el servidor, puede realizar una simple tarea diffpara determinar qué es diferente entre la versión funcional y la versión problemática.

$ diff working.sh broken.sh

También puedes hacer una diferencia en paralelo como esta:

$ diff -y working.sh broken.sh

Si el script no funciona debido a algún tipo de error tipográfico, muchas veces puedes detectarlo agregando el -xinterruptor a bash, lo que hace que sea detallado.

$ bash -x broken.sh

También puedes incorporar este interruptor en el shebang ( #!/bin/bash) en la parte superior de tus scripts de esta manera:

#!/bin/bash -x

Finales de línea

Este suele ser el problema al mover archivos de Windows a sistemas Unix/Linux. El problema tiene que ver con cómo se indican los extremos de las líneas en las 2 plataformas. Puedes leer más sobre esto aquí en Wikipedia, titulado:Nuevas líneas.

hacer un archivo de muestra

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

Como @terdon describió en su respuesta, puede usarlos sedpara eliminarlos, y a menudo también puede usar una herramienta llamada dos2unixpara hacer lo mismo. Puedes usarlo de 1 de 2 maneras:

$ dos2unix unixfile.txt

o si no desea sobrescribir el archivo existente:

$ dos2unix -n oldfile.txt newfile.txt

Cuando utilices lo anterior diffque mencioné anteriormente, obtendrás un resultado como este al comparar estos 2 archivos:

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

No podrás discernir las diferencias, sólo que están ahí. Nuevamente, la respuesta de @terdon muestra un método para solucionar el problema usando od. Por supuesto, puedes utilizar una variedad de formas de descubrir qué pasa.

usando vim

con el filecmd.

$ file unixfile.txt
winfile.txt: ASCII text 

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

Lo anterior resalta el problema de que el archivo de Windows tiene CRLF (también conocido como caracteres de retorno de carro + avance de línea al final de las líneas). Estos caracteres son 0x0D y 0x0A en hexadecimal, consulte nuevamente laArtículo de Wikipedia sobre nuevas líneassi quieres saber más al respecto.

También puedes usar vimpara ver el problema:

$ vim winfile.txt

Aquí hay una pequeña secuencia que muestra qué hacer vimpara ver el problema. Los caracteres CRLF normalmente aparecen en Unix como ^M, eso es un Ctrl+ M.

                                       ss de vim

La secuencia me muestra volviendo a abrir el archivo, winfile.txtcomo un archivo Unix formateado ( :e ++ff=unix). Esto le indica vimque no detecte automáticamente que el archivo está formateado para Windows y, por lo tanto, mostrará los ^Mcaracteres de terminación de línea.

información relacionada