shebang line funktioniert nicht mit cr-lf

10

Warum funktionieren die Shebang-Teile der folgenden elementaren Skripte nicht:

$ 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

Während das manuelle Aufrufen des Dolmetschers funktioniert:

$ sh hello.sh
Hello
$ python3 hello.py
Hello
Jamadagni
quelle

Antworten:

11

Ihre Skripte haben wahrscheinlich CR-LF-Zeilenenden im DOS-Stil und keine LF-Zeilenenden im Unix-Stil. Das in der Fehlermeldung im ersten Fall angezeigte ^ M ist ein Hinweis darauf, dass das 0D-Zeichen als Teil des Skriptinterpreternamens und nicht als Teil des Zeilenende interpretiert wurde (wie man es erwarten könnte). Da auf Ihrem System keine ausführbare Datei mit einem Pfad vorhanden ist, der das Zeichen 0D (^ M) enthält, kann das System den Interpreter nicht aufrufen. Wenn Sie Ihren Interpreter manuell aufrufen, kann er beide im Skript vorhandenen Zeilenenden verarbeiten.

Wenn Sie die Skripte so konvertieren, dass sie LF-Zeilenenden im Unix-Stil verwenden, sollte der Shebang funktionieren. Lesen Sie weiter für eine Illustration.

In der folgenden Sitzung sind todos und fromdos ein Dienstprogramm (verfügbar unter Ubuntu als Paket tofrodos) zum Konvertieren der Konventionen zum Beenden von Zeilen von CR-LF in LF. Jedes gleichwertige Dienstprogramm (siehe diese unix.SE-Frage ) würde zu Demonstrationszwecken verwendet.

Das folgende Sitzungsprotokoll (ausgeführt mit denselben Skriptdateien) sollte die Situation verdeutlichen:

$ 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
$

Es scheint, dass es der Kernel ist, der die Shebang-Zeile liest, und anscheinend erkennt der Linux-Kernel (zumindest ab der Version auf meinem Kubuntu Saucy-System) die CR nicht als Teil der CR-LF-Zeilenendkonvention.

Wenn der Shebang Ihres Skripts nicht zu funktionieren scheint (dh das manuelle Aufrufen des Interpreters des Skripts funktioniert, Sie das Skript jedoch nicht mit seinem Dateinamen ausführen können, obwohl Sie es bearbeitet haben chmod +x), ist dies ein möglicher Grund.

HINWEIS: Vielen Dank an die anderen, die ebenfalls kommentiert haben. Ich würde mich auch freuen zu hören, wenn es bessere Antworten gibt!

Jamadagni
quelle