Problem wenn Pythonprogramm als Dienst oder cronjob gestartet wird

  • Hallo Leute ich habe da ein Problem.

    ich lese Temperaturdaten ein und will die in eine mysql-Datenbank schreiben.

    Funktioniert super wenn ich das Programm von console starte.

    Wenn ich das per cronjob oder als dienst starte klappt es nicht

    Der Fehler sitzt beim Import des mysql.connektor.

    Dieser Fehler tritt bei allen Modulen auf die ich mit pip nachinstalliert habe.

    Kleines Beispielprogramm: (Logger schreibt den Text in eine Datei da ja kein Konsolenausgabe möglich ist)

    Gibt diesen Fehler:

    2022-01-29 14:54:01 --- rt gestatrtet

    2022-01-29 14:54:01 --- <class 'ModuleNotFoundError'>

    2022-01-29 14:54:01 --- No module named 'mysql'

    2022-01-29 14:54:01 --- <traceback object at 0x766402d8>

    Das gleiche passiert auch wenn ich paho.Mqtt nutzen will.

    Das muss ein Pfadproblem sein, ich finde nur keine Lösung.


    Hier die logger.py

    LG Hubertus

  • Problem wenn Pythonprogramm als Dienst oder cronjob gestartet wird? Schau mal ob du hier fündig wirst!

  • Danke für die schnelle Antwort.
    Ich benutze python3.

    Als User pi habe ich das installiert.

    sudo pip3 install mysql-connector-python

    Funktioniert ja von der Konsole aus super, nur halt nicht als Dienst

    Python
    #!/usr/bin/python
    # -*- coding: utf-8 -*-

    deutet aber auf Python2. Vielleicht solltest Du das anpassen.

    Und Du siehst ja in Deinem Beitrag #1 oben, dass die Formatierung "kaputt" ist.

    In Python ist die Einrückung relevant. Durch das ursprüngliche als-Text-Einfügen sind die Einrückungen verschwunden.

    Du könntest bei Gelegenheit nochmal den Original-Quelltext per Copy/Paste oben einfügen, also den unglücklich formatierten Text ersetzen. ;)

    Wie hast Du die Versuche "als Dienst" genau gemacht?

    Da kommt es u.a. auf den konfigurierten Benutzer an. Weil auch DER muss die installierten Module finden.

    Dieses Thema kommt hier im Forum alle paar Tage...

  • Wenn ich das per cronjob oder als dienst starte klappt es nicht

    Dieser Fehler tritt bei allen Modulen auf die ich mit pip nachinstalliert habe.

    sudo pip3 install ...

    Du verwendest die Usercrontab von pi, richtig? Du hast die Module mit sudo installiert, was nicht wirklich eine gute Idee war.

    Entweder Du installierst die Module nochmals ohne sudo oder Du versuchst es mit der Crontab von root (sudo crontab -e).

    Zeige auch mal bitte den Eintrag in der Crontab! Vielleicht ist auch das nötige Netztwerk noch nicht oben.

  • Um zu verstehen, wieso das Problem überhaupt auftritt, muss man ein wenig ins Detail gehen.

    Der Python-Interpreter sucht nach Standard-Pfaden, die abhängig vom Ort des Interpreters sind.

    Zusätzlich wird das lokale Verzeichnis, in dem sich das Programm befindet, hinzugefügt.

    Wenn ein User das Programm startet, wird auch ~/.local/lib/python3.9/ zum Suchpfad für Module hinzugefügt.

    Testen kann man z.B. so:

    Dann mit dem User pi einen crontab anlegen:

    Code
    export EDITOR=nano
    crontab -e

    Dann folgenden Inhalt hinzufügen:

    Code: crontab
    # PYTHONPATH=/home/pi/.local/lib/python3.9/site-packages
    */1 * * * * ~/p.py

    Dann beobachten:

    Code
    sudo journalctl --unit cron -f

    Dann auf den Fehler warten.

    Mit STRG+C abbrechen und dann noch mal mittels crontab -e vor PYTHONPATH das # Zeichen entfernen.

    Dann nochmals beobachten:

    Code
    sudo journalctl --unit cron -f

    Natürlich unterscheiden sich die Pfade, da ich das lokal auf meinem Desktop getestet habe und pyenv verwende.

    PS: Unter Arch Linux heißt der Dienst cronie. Auf dem RPi sollte der Dienst cron heißen.

  • egal ob mit #PYTHONPATH oder PYTHONPATH es funktioniert nicht.

    crontab -e

    PYTHONPATH=/home/pi/.local/lib/python3.7/site-packages

    * * * * * sudo /usr/bin/python3 /home/pi/python/p.py & >> /home/pi/python/log2.txt

  • egal ob mit #PYTHONPATH oder PYTHONPATH es funktioniert nicht.

    Bei dir wird Python 3.7 verwendet.

    Code
    PYTHONPATH=/home/pi/.local/lib/python3.7/site-packages

    Und vorher kannst du mal nachsehen, was in lib ist.

    Code
    ls -l /home/pi/.local/lib/

    Es sollte unter anderem python3.7 gelistet sein, sofern mit dem User pi Python-Pakete lokal installiert worden sind.

    Python 3.9 ist mit Debian Bullseye eingeführt worden. Das deutet darauf hin, dass du noch RPI OS (Debian Buster) verwendest, was aber nicht unbedingt ein Grund sein muss jetzt zu wechseln.

  • Hallo,

    hast du das schon mal als systemd Service Unit probiert? Da kannst du pro Unit den Nutzer festlegen, mit dessen Rechten das ganze läuft. Bzw. im Falle von Python auch, auf welche lokal installierten Module Python zugreifen kann.

    Außerdem kannst du dir die ganzen Umleitungen sparen, weil alles in Journal von systemd geloggt wird.

    Gruß, noisefloor

    Ja das habe ich, gleiche Ergebnis. Das Programm wird gestartet aber die Einbindung klappt nicht.

    Hier fällt auf, das beim Start über den Service Path:/home/pi/.local/lib/python3.7/site-packages nicht in der sys.path erscheint


    Zitat von noisefloor

    Da kannst du pro Unit den Nutzer festlegen, mit dessen Rechten das ganze läuft. Bzw. im Falle von Python auch, auf welche lokal installierten Module Python zugreifen kann.

    Wie das geht ist mir (noch) nicht bekannt.

  • Hallo,

    der Log des manuellen Starts zeigt doch, dass das MySQL Modul lokal = für den Nutzer `pi` installiert ist.

    So wie die Unit geschrieben ist, wird die als `root` ausgeführt -> kein Modul vorhanden, weil für `root` bzw. systemweit nicht installiert - was auch Sinn macht.

    Wenn du in der Unit im Abschnitt `[Service]` die Direktive `User=pi` einfügst sollte es klappen.

    Und das `/dev/null ...` kannst du an der Stelle aus der Unit raus nehmen, das ist das Quatsch. Das darf gerne alles in Journal von systemd laufen, macht die Fehlersuche einfacher.

    Das `After=multi-user.target`ist auch nur semi-sinnvoll, weil das mulit-user.target ja deine Unit starten soll -> Widerspruch in sich. Wenn deine Unit irgendwas braucht, um zu funktionieren, dann solltest du das passende .target referenzieren. Z.B. bei allem, was eine Netzwerkverbindung braucht: `After=network-online.target`.

    Gruß, noisefloor

  • Hier wäre vielleicht auch mal die Ausgabe von

    Code
    python3 -m pip show paho-mqtt

    hilfreich. (Das dauert einen Moment, bis etwas angezeigt wird!)

    pi@heizungspi-2022:~/python $ python3 -m pip show paho-mqtt

    Name: paho-mqtt

    Version: 1.6.1

    Summary: MQTT version 5.0/3.1.1 client class

    Home-page: http://eclipse.org/paho

    Author: Roger Light

    Author-email: roger@atchoo.org

    License: Eclipse Public License v2.0 / Eclipse Distribution License v1.0

    Location: /home/pi/.local/lib/python3.7/site-packages

    Requires:

    Required-by:

    clear

  • Problem erkannt und fast gebannt.

    Danke noisefloor

    Mit sudo python3 rt.py klappt es auch nicht.

    Nun muss ich nur noch lernen wie ich das mit dem user pi als service ausführe.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!