Auslesen einer .INI Datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tueftler
User
Beiträge: 3
Registriert: Freitag 17. Juni 2016, 06:19

Hallo Forum!

ich habe ein Problem, welches mich zur Verzweiflung treibt und hoffe, ihr könnt mir helfen...

Ich nutze python3 auf einem Raspberry Pi mit Raspian 7.10, welcher durch apt-get update und apt-get upgrade aktuell gehalten ist.
Das Python-Script soll aus einer .ini Datei Variablen auslesen, um den weiteren Programmablauf zu steuern. (diese .ini wird dabei via php und einer Weboberfläche verändert)
Es gibt den Benutzer pi, die Einstellungsdatei liegt in dessem Heimverzeichnis unter dem Namen settings.ini
Der RPi läuft headles im Verteilerschrank.


Folgender Code (gekürzt) im Python-Script, welches den Name start1.py trägt:

Code: Alles auswählen

#!/usr/bin/env python3

import sys
import os
from configparser import ConfigParser

config = ConfigParser()
onfig.read('/home/pi/settings.ini')

variable = int(config.get('bereich', 'variable'))

# weiterer Programmablauf basierend auf variable

Die Datei habe ich mit chmod +x start1.py ausführbar gemacht.
Diese Datei soll ein Relais schalten; ich habe mehrere Relais, daher auch mehere Dateien (start1.py, start2.py, start3.py...)
Um alles auf einmal zu starten, habe ich die Startaufrufe in einer Datei zusammengefasst, "startall" (welche ebenso ausführbar ist)

Inhalt /home/pi/startall:

Code: Alles auswählen

#!/bin/bash

/home/pi/start1.py &
/home/pi/start2.py &

Wenn ich mich nun via PuTTY als pi anmelde und ./start1.py oder ./start eingebe, funktioniert das Script tadellos und alles verhält sich wie erwartet. Wenn ich mit als root anmelde, klappt ebenso alles.

Allerdings läuft es nicht, wenn ich es automatisch bei Systemstart ausführen lassen möchte...

Aufruf in der /etc/rc.local:

Code: Alles auswählen

/home/pi/startall

Ich konnte den Fehler in so weit eingrenzen, dass, wenn ich die Zeile

Code: Alles auswählen

config.read('/home/pi/settings.ini')
auskommentiere und die Variable mit

Code: Alles auswählen

variable=1
zuweise, die automatische Ausführung klappt. Es hängt somit tatsächlich am config.read

Und nun die Frage: WARUM?

Warum klappt es, als Benutzer die Datei korrekt auszuführen, als System jedoch nicht?!


Vielen Dank für Eure Hilfe und lg
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Python gibt ja normalerweise sehr aussagekräftige Fehlermeldungen - wie ist denn die exakte Fehlermeldung?
Wenn du den Fehler auf die besagte Zeile eingrenzen kannst muss ja irgendwas beim Lesen der Datei schief gehen.

Was hast du denn in den Datei `rc.local`eingetragen?

Gruß, noisefloor
tueftler
User
Beiträge: 3
Registriert: Freitag 17. Juni 2016, 06:19

Guten Morgen

und Danke für die rasche Antwort.

Der Aufruf der "startall" in der rc.local funktioniert ja, wenn ich die beschriebe Zeile im script auskommentiere, klappt es ja tadellos.
Die entsprechende Zeile habe ich in meinem Beitrag ja gepostet.

Eine Fehlermeldung erhalte ich nicht, ich starte ja headless... der manuelle Aufruf im Terminal klappt ja, nur beim automatischen Start funktioniert es nicht.
--> gibt es ein Logfile wo eine mögliche Fehlermeldung protokolliert wird? Wo ist es zu finden?


Danke und lg
BlackJack

@tueftler: Zwei Vermutungen:

* Darf der Benutzer unter dem `rc.local` ausgeführt wird die Datei lesen?
* Enthält die INI vielleicht irgendwas was bei dem Benutzer der die `rc.local()` ausführt zu Problemen führen kann? Zeichen ausserhalb von ASCII vielleicht? Es wäre sowieso sicherer wenn man die Kodierung beim Lesen explizit angibt. Das Märchen das mit Python 3 Unicode viel einfacher geworden ist, ist nämlich genau das — ein Märchen. :-)
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

Also wenn das Programm so funktioniert, wie du es erwartest dann liegt es vielleicht nicht am Programm. Wie führst du das Programm manuell aus? Welche Zugangsberechtigung ist nötig? Welches Programm führt den Autostart aus?
Vielleicht muss dein Programm in eine Arbeits-Gruppe, die die notwendige Berechtigung für die Ausführung hat. Oder es fehlen Einstellungen für den Autostarter. Benutzt du da daemons? Kenne mich jetzt mit Raspberry Pi und dem OS nicht aus.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
gibt es ein Logfile wo eine mögliche Fehlermeldung protokolliert wird?
Guck mal in den syslog.

Ansonsten kannst du auch stdout und stderr bei Aufruf in eine Datei umleiten und dahin loggen.

Gruß, noisefloor
SeBu
User
Beiträge: 16
Registriert: Samstag 4. Januar 2014, 11:36

Funktioniert es denn, das Skript über crontab auszuführen?

Um das auszuprobieren:

Melde dich als Benutzer pi an.

Code: Alles auswählen

crontab -e
Dort fügst du ein:

Code: Alles auswählen

@reboot /Pfad/zum/Skript

# Oder gleich jedes Skript einzeln mit:
@reboot python3 /Pfad/zum/Skript.py

Dann testen, ob es nun beim Neustart korrekt ausgeführt wird. (Natürlich vorher den anderen Autostart Eintrag entfernen)
tueftler
User
Beiträge: 3
Registriert: Freitag 17. Juni 2016, 06:19

@BlackJack
Darf der Benutzer unter dem `rc.local` ausgeführt wird die Datei lesen?
Ja, denn wenn ich kein config.read() im Script verwende, funktioniert es ja.
Zeichen ausserhalb von ASCII vielleicht?
Das schliesse ich aus, Grund wie oben. Zusätzlich habe ich die Datei mit vi auf die typischen ^M an den Zeilenenden überprüft -> negativ. Des Weiteren lese und schreibe ich die Werte auch mit einem php-Script, da ich diese über eine Weboberfläche verändern möchte, auch hier kein Thema.


@Py19917062
Wie führst du das Programm manuell aus?
mit ./startall oder ./start1.py über eine PuTTY Sitzung als user "pi", wenn ich im Heimverzeichnis (/home/pi/) bin, für jene Scripte, wo ich die GPIOs benötige, mit vorangestelltem sudo.
Welche Zugangsberechtigung ist nötig?
s. o. - sobald über rc.local ausgeführt wird, sind ohnehin SU-Rechte vorhanden.
Welches Programm führt den Autostart aus?
Aufruf in rc.local
Vielleicht muss dein Programm in eine Arbeits-Gruppe, die die notwendige Berechtigung für die Ausführung hat.
Ich denke nicht, da, wenn ich die Zeile mit config.read() auskommentiere, das Script ja gestartet wird und funktioniert.


@noisefloor
Guck mal in den syslog.
Habe ich getan - und mittels grep py gefiltert... kein Eintrag zu finden... :/


@SeBu
Das ist eine fabelhafte Idee! Ich werde es morgen testen können, da ich momentan nicht zu Hause bin. Notiz an mich selbst: soweit ich weiss, wird das Script dann als Benutzer "pi" ausgeführt... werde daher vermutlich ein "sudo" voranstellen müssen, um auf die GPIOs zugreifen zu können.



Vielen Dank an alle und schönen Restsamstag, lg
SeBu
User
Beiträge: 16
Registriert: Samstag 4. Januar 2014, 11:36

tueftler hat geschrieben:soweit ich weiss, wird das Script dann als Benutzer "pi" ausgeführt... werde daher vermutlich ein "sudo" voranstellen müssen, um auf die GPIOs zugreifen zu können.
Stimmt genau, also

Code: Alles auswählen

sudo crontab -e
und dann dort eintragen.
BlackJack

@tueftler: Kodierung kannst Du nicht einfach so ausschliessen nur weil das für Dich in einem Terminal läuft. Selbst dann würde ich die Kodierung immer explizit angeben. Alles andere ist russisches Roulette.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Habe ich getan - und mittels grep py gefiltert...
Filter auf `py` ist IMHO falsch bzw. birgt die Gefahr, dass der Filter falsch ist. Wenn Filtern, dann auf `*Error*` (wie auch immer die RegEx auch genau aussieht).

Ansonsten: leite dir beim Aufruf des Python-Skript stdout und stderr in eine Datei um.

Gruß, noisefloor
Antworten