la línea shebang no funciona con cr-lf

10

¿Por qué las partes shebang de los siguientes scripts elementales no funcionan?

$ cat hello.sh
#! /bin/sh
echo Hello
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory

$ cat hello.py
#! /usr/bin/env python3
print("Hello")
$ ./hello.py
: No such file or directory

mientras que llamar al intérprete manualmente funciona:

$ sh hello.sh
Hello
$ python3 hello.py
Hello
jamadagni
fuente

Respuestas:

11

Sus scripts probablemente tengan terminaciones de línea CR-LF de estilo DOS y no terminaciones de línea LF de estilo Unix. La ^ M que se ve en el mensaje de error en el primer caso es una indicación de que el carácter 0D se interpretó como parte del nombre del intérprete de script y no como parte del final de la línea (como cabría esperar). Como no hay ningún archivo ejecutable en su sistema con una ruta que incluya el carácter 0D (^ M), el sistema no puede invocar al intérprete. Cuando llama manualmente a su intérprete, puede manejar ambos tipos de terminaciones de línea presentes en el script.

Si convierte los scripts para usar terminaciones de línea LF de estilo Unix, debería ver el shebang funcionando. Sigue leyendo para ver una ilustración.

En la siguiente sesión, todos y fromdos son una utilidad (disponible en Ubuntu como paquete tofrodos) para convertir las convenciones de final de línea de CR-LF a LF. Cualquier utilidad equivalente (ver esta pregunta de Unix.SE ) lo haría con fines de demostración.

La siguiente transcripción de sesión (ejecutada con los mismos archivos de script) debería aclarar la situación:

$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$

Se parece que es el núcleo que se lee la línea tinglado, y al parecer el núcleo de Linux (al menos a partir de la versión en mi sistema para Salsas Kubuntu) no reconoce el CR como parte de la línea de CR-LF termina convención.

Si el shebang de su secuencia de comandos no parece funcionar (es decir, llamar manualmente al intérprete en la secuencia de comandos funciona pero no puede ejecutar la secuencia de comandos utilizando su nombre de archivo aunque lo haya hecho chmod +x), entonces esta es una posible razón.

NOTA: Gracias a los otros que comentaron también. ¡También me alegraría saber si hay mejores respuestas!

jamadagni
fuente