Python Skript per Autostart ausführen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Guten Tag zusammen.
Ich habe ein Problem und zwar möchte ich ein Skript direkt beim Start ausführen. Hierbei sollte sich ein Fenster öffnen. Dies soll dann in naher Zukunft ein über ein Touch-Display laufen, damit man das Programm direkt bedienen kann. So jetzt habe ich das Skript ausführbar gemacht. Über das Terminal kann ich das Skript ausführen, wenn ich "/home/shares/test/Raspberry/Interface1.py" eingebe, öffnet sich das Fenster sprich das Skript ist ausführbar. Jetzt habe ich zuerst versucht es als Autostart in einem Cronjob auszuführen. Hierfür bin ich wie folgt vorgegangen: "crontab -e" dann die 2 ausgewählt. Dort dann "@reboot /home/shares/test/Raspberry/Interface1.py" eingegeben. System neu gestartet aber es passiert nichts. Danach habe ich versucht mit "sudo nano /etc/rc.local" und am Ende vor exit 0 folgendes eingetragen: "/home/shares/test/Raspberry/Interface1.py &" eingegeben aber es passiert ebenfalls nichts. Danach wollte ich einen anderen Weg über "cd /home/pi/.config/autostart" versuchen, allerdings kommt dann immer der Fehler, dass das Verzeichnis nicht gefunden wurde.
Kann mir jemand helfen bzw. einen anderen Weg aufzeigen?
Ich danke schonmal im Vorraus.
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Ok ich habe jetzt hier https://wiki.ubuntuusers.de/systemd/Service_Units/ eine Lösung gefunden die auch in einem anderen Thread stande. Leider zu spät gesehen :oops: allerdings obwohl ich die Unit gestartet habe passiert beim Start nichts. Die Unit sieht so aus:

[Unit]
Description=Interface

[Service]
Type=simple
ExecStart=/home/shares/test/Raspberry/Interface1.py

[Install]
WantedBy=reboot.target

Ich hoffe Ihr könnt mir helfen. Ich sitze jetzt schon den ganzen Tag daran und kriege diesen Sch*** einfach nicht hin.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn das Skript startet obwohl der X-Server noch nicht oben ist, stirbt es. Ich weiss nicht ob der X-Server auch als systemd-unit gestartet wird, aber wenn, dann sollest du darauf warten koennen. Und ansonsten musst du eben den Autostart-Mechanismus deines window-managers bemuehen. Der sollte zur not auch haendisch per Systemeinstellung oder aehnlichem herkonfigurierbar sein.
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Tut mir leid aber ich verstehe gerade garnichts :shock: ich bin noch ein ziemlicher Anfänger was programmieren an geht und erst Recht was Linux bzw Python angeht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die grafische Benutzeroberflaeche ist ein Programm wie jedes andere auch. Wenn das Programm nicht laeuft, kann ein anderes Programm, das darauf angewiesen ist, dass sie laeuft, eben auch nicht laufen.

Systemd-Units koennen auf andere Units warten. Es bringt zB nix eine Datenbank oder einen Webserver zu starten, ohne das das Netzwerk schon aufgesetzt ist. Also warten die darauf, dass eben das Netzwerk hochgefahren wird, bevor sie gestartet werden. *WENN* der X-Server (unbekannte Begriffe kann man googeln) noch nicht laeuft, dann kann deine Unit ggf. darauf warten. Ich weiss aber nicht, ob der als Systemd-Unit gestartet wird.

Und auch unter Windows kennt man Autostart-Programme. So etwas gibt es bei Linux auch. Dann startet der Windowmanager (das Programm, das dir Fensterdekorationen wie den Schliess-Knopf gibt, und Rahmen zum Groesse andern etc) dein Programm eben selbst.

Man muss halt rausfinden, wie die fuer dein System konfiguriert werden. Da ich das nicht kenne, kann ich dir das nicht sagen. Prinzipiell sieht das so aehnlich aus wie dein gescheiterter Versuch mit dem .../.config/autostart, aber du musst schon ein bisschen rumsuchen, wenn irgendwo aus dem Netz kopierte Rezepte nicht klappen.

Um rauszufinden, welche services laufen, und ob der x-server dabei ist, kannst du mal mit "systemctl | grep running" spielen & posten, was da rauskommt.
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Ok danke für die bessere Erklärung. Ich sitze da schon den ganzen Tag dran und mein Kopf ist langsam ziemlich voll xD.

Also wenn ich sudo systemctl is-enabled Interface.service sagt er mir, dass die Unit enabled ist. Jedoch gibt er kein Fenster aus.

Ich suche dann mal die Funktion wie die Unit wartet. Besten Dank schon mal.

Ich habe meinen Gedankenfehler schon entdeckt. Er ist "enabled" aber nicht "active". Naja ich google mal weiter irgendeine Lösung muss es ja geben.
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Also wenn ich "sudo service Interface status" eingebe bekomme ich folgende Meldung:
● Interface.service - Interface
Loaded: loaded (/etc/systemd/system/Interface.service; enabled; vendor preset
Active: failed (Result: exit-code) since Fri 2018-03-23 19:02:43 CET; 12s ago
Process: 1210 ExecStart=/home/shares/test/Raspberry/Interface1.py (code=exited
Main PID: 1210 (code=exited, status=1/FAILURE)

Mär 23 19:02:42 raspberrypi systemd[1]: Started Interface.
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: Traceback (most recent call las
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: File "/home/shares/test/Raspb
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: root = Tk() # Fenster erste
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: File "/usr/lib/python3.5/tkin
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: self.tk = _tkinter.create(s
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: _tkinter.TclError: no display n
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Main process exited,
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Unit entered failed s
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Failed with result 'e
lines 1-16/16 (END)...skipping...
● Interface.service - Interface
Loaded: loaded (/etc/systemd/system/Interface.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-03-23 19:02:43 CET; 12s ago
Process: 1210 ExecStart=/home/shares/test/Raspberry/Interface1.py (code=exited, status=1/FAILURE)
Main PID: 1210 (code=exited, status=1/FAILURE)

Mär 23 19:02:42 raspberrypi systemd[1]: Started Interface.
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: Traceback (most recent call last):
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: File "/home/shares/test/Raspberry/Interface1.py", line 25, in <modul
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: root = Tk() # Fenster erstellen
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: File "/usr/lib/python3.5/tkinter/__init__.py", line 1880, in __init_
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: self.tk = _tkinter.create(screenName, baseName, className, interac
Mär 23 19:02:43 raspberrypi Interface1.py[1210]: _tkinter.TclError: no display name and no $DISPLAY environment variabl
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Main process exited, code=exited, status=1/FAILURE
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Unit entered failed state.
Mär 23 19:02:43 raspberrypi systemd[1]: Interface.service: Failed with result 'exit-code'.
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
lines 1-16/16 (END)

Kann wer damit was genaueres anfangen?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist exakt der erwartete Fehler. Du startest dein Programm zu früh. Es gibt noch keine X-Server. Du musst Nunmal auf den warten.
jens233
User
Beiträge: 7
Registriert: Samstag 17. März 2018, 22:42

würde es einfach so machen
in die /etc/rc.local,
dann den Eintag so machen:

sleep 20 && /home/shares/test/Raspberry/Interface1.py

oder wenn das Skript unter ROOT laufen muss:

sudo sleep 20 && /home/shares/test/Raspberry/Interface1.py

die 20 steht für 20 Sekunden bis alles andere geladen ist,
sonst vielleicht auf 25 oder… erhöhen...
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

rc.local ist immer Root, und wenn es das nicht wäre, würde dein Kommando mit root rechten ganze besonders privilegiert schlafen, aber immer noch normal ausgeführt werden.

Und wenn man auf den X-Server wartet, muss man nicht einen geratenen timeout verwenden.
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Ok also kann ich in der rc.local warten? sonst keine idee wie das gehen soll. Habe vorhin auch nichts im Internet gefunden. wenn das keine geratene Zeit ist wie kriege ich die dann raus? Ich werde das morgen auf jeden Fall probieren
jens233
User
Beiträge: 7
Registriert: Samstag 17. März 2018, 22:42

dann vielleicht besser in,
\home\pi\.config\lxsession\LXDE-pi\autostart, eintragen ???

aber, das mit der geratenen Zeit, in der /etc/rc.local,
hat durch Probieren, bei mir eigentlich immer funktioniert...
jens233
User
Beiträge: 7
Registriert: Samstag 17. März 2018, 22:42

__deets__ hat geschrieben:rc.local ist immer Root, und wenn es das nicht wäre, würde dein Kommando mit root rechten ganze besonders privilegiert schlafen, aber immer noch normal ausgeführt werden.

Und wenn man auf den X-Server wartet, muss man nicht einen geratenen timeout verwenden.
@ __deets__ ,

eine Frage hab ich da noch,

hab mein Skript auch mit 20 Sekunden Verzögerung in der
/etc/rc.local, gestartet,
aber, das funktioniert nur mit vorangestelltem sudo ???
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

sudo foo && bar

führt foo mit sudo aus. bar aber ohne. Das sind zwei komplett getrennte Kommandos. Das && sagt „warte auf das Kommando links von mir, und wenn das gut ging, mach das rechts von mir“

Und das sudo steht nur links. Also ist auch links nur sudo.

Nur ist das vollkommen egal. Weil ALLES in der rc.local eh mit Root rechten läuft.

Das es klappt zu warten ist richtig. Es ist halt frickeliger Mist, aber schön und gut wird auf dem PI eh nix gemacht. Nur wenn dann mal das eine mal der dhcp Server länger braucht & darum der ganze Start auch verzögert, krachts halt :K
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

https://wiki.ubuntuusers.de/rc.local/

Da steht’s nochmal - alles immer Root. Das es bei dir ohne sudo nicht klappt ist also nicht richtig. Weil es ja eh nur das sleep wäre was du als Root ausführst. Und das braucht das nun wirklich nicht.
jens233
User
Beiträge: 7
Registriert: Samstag 17. März 2018, 22:42

@ __deets__ ,

hast Recht, gerade nochmal Probiert…
das sudo braucht man nicht…


kein Plan ob Du dann eine Saubere Lösung für Theynk sein Problem hast ???

hätte da auch noch ein Problem:
viewtopic.php?f=31&t=42438
hab erst mal Serverseitig was ändern lassen.

das eigentliche Problem würde mich immer noch interessieren.

Wie gesagt, befasse mich nun erst 14 Tage mit Python…
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Also ich habe jetzt "sleep 30 && /home/shares/test/Raspberry/Interface1.py" eingegeben allerdings tut sich immer noch nichts. Bekomme diese Meldung:
● Interface.service - Interface
Loaded: loaded (/etc/systemd/system/Interface.service; enabled; vendor preset
Active: failed (Result: exit-code) since Fri 2018-03-23 23:17:22 CET; 1min 25
Process: 341 ExecStart=/home/shares/test/Raspberry/Interface1.py (code=exited,
Main PID: 341 (code=exited, status=1/FAILURE)

Mär 23 23:17:18 raspberrypi systemd[1]: Started Interface.
Mär 23 23:17:22 raspberrypi Interface1.py[341]: Traceback (most recent call last
Mär 23 23:17:22 raspberrypi Interface1.py[341]: File "/home/shares/test/Raspbe
Mär 23 23:17:22 raspberrypi Interface1.py[341]: root = Tk() # Fenster erstel
Mär 23 23:17:22 raspberrypi Interface1.py[341]: File "/usr/lib/python3.5/tkint
Mär 23 23:17:22 raspberrypi Interface1.py[341]: self.tk = _tkinter.create(sc
Mär 23 23:17:22 raspberrypi Interface1.py[341]: _tkinter.TclError: no display na
Mär 23 23:17:22 raspberrypi systemd[1]: Interface.service: Main process exited,
Mär 23 23:17:22 raspberrypi systemd[1]: Interface.service: Unit entered failed s
Mär 23 23:17:22 raspberrypi systemd[1]: Interface.service: Failed with result 'e


Ist das noch der gleich Fehler? Da da jetzt ja eindeutig weniger ist. Was ich mich gefragt habe, muss das nicht der Verweis auf die Unit sein?

Wenn ich ins Terminal "sudo /etc/rc.lokal" eingebe gibt der mir meine IP aus und nach 30sek öffnet der das gewünschte Interface allerdings nicht beim Start.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du bist nach folgender Anweisung vorgegangen: https://webnist.de/autostart-0eines-pyt ... pberry-pi/.
Das wäre gut zu wissen, dann kann man konkreter helfen.

DA fehlt eigentlich nur, dass man das Verzeichnis anlegen sollte, falls es nicht existiert.
[codebox=bash file=Unbenannt.bsh]mkdir ~/.config/autostart[/code]
Theynk
User
Beiträge: 22
Registriert: Donnerstag 8. März 2018, 14:20

Ich bin nach sehr vielen Anleitungen vorgegangen da ja nichts geklappt hat xD
Wenn ich deinen Link öffne, kommt da nur, dass die Seite nicht gefunden wurde. Also wenn ich die System-Unit angelegt habe, die Verzögerung in rc.local eingetragen haben muss ich noch /.config/autostart machen? Wenn ja welchen Pfad muss ich da genau nutzen und was muss da noch rein? Wäre super wenn ich mir das hier sagen könntet, dann muss ich wenn ich heute Abend wieder zuhause bin nicht direkt googlen :roll:
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Autostart per window manager ist eine andere Methode als die Unit. Das macht man entweder oder.
Antworten