Shebang! Oder wie man Python weglässt

Ein selbstgeschriebenes Python Programm auf dem Raspberry Pi immer mit python programm.py zu starten, ist irgendwie nervig. Zumal andere Python Programme meist ohne das python vornedran auskommen. Wie kann ich also ein selbstgeschriebenes Python Programm ohne das python davor aufrufen?

Anders als bei DOS oder Windows ist es Debian Linux herzlich egal, welches Suffix eine Datei oder ein Programm hat. Ob z.B. ein Python Programm check.py oder check.blah heißt ist wurscht. Damit Linux weiß, was es mit einem Programm tun soll, das gerade aufgerufen wird, schaut es sich den Dateiheader, d.h. die erste Zeile an. Steht da nichts Besonderes, das Linux mitteilt, was eigentlich zu tun ist, gibt’s eine Fehlermeldung und fertig. Mit python vornedran wird der Python Interpreter aufgerufen und die dahinter angegebene Datei abgearbeitet.

Dass Python Programme ein Suffix .py haben, ist reine Konvention und dient nur der Ordnung.

Wie kann ich nun Python Programme aufrufen, ohne python davor zu schreiben?

Dazu dient das sogenannte Shebang, das Linux mitteilt, dass der Python Interpreter aufzurufen ist. Das Shebang wird als allererste Zeile in einem Python Programm geschrieben…
#!/usr/bin/python
…und teilt Linux mit, dass es die aufgerufene Textdatei mit dem in /usr/bin wohnenden Python Interpreter aufrufen soll. Zumindest bei Raspbian liegt er dort. Bei anderen Distributionen kann das auch anderswo sein.

Theoretisch müsste jetzt das Programm checkinet.py durch Eingabe von
checkinet.py
starten. Leider nein! Linux ist für einen Nutzer, der Windows gewohnt ist etwas umständlich aber dafür sehr viel gründlicher: Die Datei muss von den Berechtigungen her noch als “ausführbar” markiert werden. Das geht so:
chmod +x checkinet.py
oder, für den Fall, dass sich die Datei in einem fremden, für den User Pi nicht so ohne Weiteres beschreibbaren Verzeichnis befindet:

Und, klappt es jetzt? Mitnichten! Warum auch immer, Linux denkt hier  m.E. etwas zu kurz und stellt sich blöd: Es muss der Pfad explizit mit angegeben werden. Zumindest in relativer Form als
./checkinet.py
wenn du dich in dem Verzeichnis befindest, in dem das Programm liegt oder absolut als
/home/pi/433mhz/checkinet.py
wenn du dich irgendwo anders im Dateisystem befindest.

Trotzdem klappt dieser Aufruf nicht immer und es hat eine ganze Weile gedauert, bis ich drauf gekommen bin:

Vorsicht, Schreibmaschine!

Solltest du deine Python Programme nicht direkt auf dem Pi editieren (z.B. mit nano), sondern auf einem Windows Rechner, kann es sein, dass der von dir verwendete Editor andere – unsichtbare  – Zeilenkommandos in den Programmcode einfügt als bei Linux üblich. Linux verwendet für eine neue Zeile das Zeichen für LF (Linefeed oder ASCII Char10), wohingegen Windows zwei  Zeichen dafür einfügt, nämlich CR (Carriage Return oder ASCII Char13) und LF. Linux akzeptiert das zwar beim Aufruf mit dem python Prefix aber leider nicht beim direkten Aufruf. Blöd, is aber so.

Immer wieder erstaunlich, welche Uralt Technologie sich hinter manchen Begriffen versteckt. CR = Carriage Return (Wagenrücklauf) und LF = Line Feed (Zeilenvorschub) sind Begrifflichkeiten aus der Fernschreiber und Schreibmaschinen Ära.

Kopiert man ein in Windows editiertes Programm (z.B. mit WinSCP) auf den Pi und der Editor kann keinen Linux Zeilenvorschub, klappt der direkte Aufruf nicht.

Abhilfe gibt es durch das Programm dos2unix, welches die Windows (=DOS) Zeilenvorschübe auf Linux übersetzt.

Ist es auf dem Pi nicht vorhanden, kann man es durch

nachinstallieren. In unserem Fall würden wir mit

das Programm konvertieren und alles läuft wie gewünscht.

5 Gedanken zu „Shebang! Oder wie man Python weglässt

  1. Hallo,

    danke für die wirklich sehr hilfreichen Hinweise. Ich will demnächst nach 3 Jahren Pause bedingt durch Umzug usw. endlich mein altes Projekt VLF – Empfänger über USB-Soundmodul und Paspi endlich durchziehen und damit meine py-Kenntnisse wieder auffrischen, da paßt das hier gut rein.

    Falls ich im Gegenzug mit Tipps zum 3D- Druck oder einen Druck selbst mal aushelfen kann, bin ich dazu gern bereit.

    Mit freundlichen Gruß von Uwe (DL5KU)

  2. Echt Hamer, ohne das man die Seiten verlassen mus, kommt man auf alle Infos die weiter helfen, gut durchdacht und eine menge Arbeit eingebracht, RESPECKT!!!!!

    Danke und weiterhin viel erfolg!!!!

    Ich versuche gerade, mit Json Wetterdaten abzurufen, mit dem Ziel das ich die Daten in eine Datenbank abspeichere und diese als Historie mit meinen Aufgezeichneten daten auf ein Webserver darzustellen. Bin erst gerade soweit, das ich ein request absenden kann und jetzt versuche ein Phyten script aufzusetzen, den Teil die Infos in die Datenbank einzukippen muss ich noch erarbeiten.

    Gruß
    Abd 🙂

  3. Danke für den Tip mit dem dos2unix. Nach geschätzten 3 Stunden Suche und Testen mit allen möglichen Variationen hat ihr Beitrag geholfen damit nicht schon am ersten Tag mit Linux/Raspberry und Co der Frust ausbricht.

    Vielen Dank
    Grüße
    G.R.

  4. Hallo,
    danke erst einmal für das Lob. Ich habe zwar inzwischen 200 echte Besucher am Tag, aber die wenigsten hinterlassen etwas…
    Alias Befehle kannst du/können Sie am besten in die Datei .bashrc einbauen. Das ist eine versteckte Datei im Home Verzeichnis – mit dem Punkt vorne dran wird sie von ls normalerweise nicht angezeigt. (mit ls -a aber schon)
    Einfach mit nano .bashrc editieren und am besten ganz oben die Aliasbefehle reinschreiben. Bei mir sieht das so aus:
    alias dir=’ls -1 -h -l’
    alias failed=”grep -a ‘WARNING’ /var/log/fail2ban.log”
    alias restartwebserver=”sudo service lighttpd force-reload”
    alias webcam =”ssh -p 10099 localhost”

    Beim Starten einer Sitzung (z.B. mit Putty) wird die .bashrc abgearbeitet und die Aliases werden automatisch gesetzt.

    Gruß aus Oberbayern
    Chris

  5. Hallo und herzlichen Dank für Ihre Scripts, die ich seit einigen Tagen zum Einstieg in Python verwende.

    Es bietet sich auch an oft verwendete Scripts via alias zu starten.

    bei mir habe ich z.B. in der Datei

    ~/.bash_aliases

    alias ls=’ls -l ‘
    alias webcam=’python /home/pi/tweeter/doimage.py ‘

    angelegt.

    Wünsche Ihnen weiterhin viel Freude mit dem Raspberry

    hdb

Schreibe einen Kommentar zu gr Antworten abbrechen

Ich freue mich über Lob und Kritik.
Falls du Probleme mit der hier vorgestellten Anleitung hast und nicht weiter kommst:
Bitte das Problem oder die Fehlermeldung(en) möglichst genau beschreiben, auch an welcher Stelle (z.B. in welchem Node oder Befehl) und unter welchen Umständen der Fehler auftritt.
Gerne kannst du mir auch ein Mail schreiben. Die Adresse findest du im Impressum.
Ich gebe mir viel Mühe, meinen Lesern weiterzuhelfen. Je konkreter du bist, desto einfacher und schneller kann ich versuchen zu helfen.
Deine E-Mail-Adresse wird nicht veröffentlicht.
Erforderliche Felder sind mit * markiert