Raspberry Pi: Autostart von Programmen einrichten

30 Jul
30. Juli 2014

Auf dem Raspberry Pi kommt häufig Raspbian und folglich Debian Linux zum Einsatz. Bei den Zahlreichen Tutorials, die ich bereits über den kleinen Computer schrieb, kam häufiger die Frage auf, sofern ich es nicht beschrieb, wie man ein bestimmtes Programm in den Autostart packt. Hierfür gibt es mehrere Möglichkeiten. Da sich diese Frage auch bei einem beliebigen Programm, bei dem ich nicht in einem separaten Artikel die genaue Vorgehensweise beschrieb, stellen kann, werde ich im Folgenden beschreiben wie man allgemein Programme in Debian (auf dem Raspberry Pi) automatisch mit dem Boot des Gerätes starten lassen kann.

Voraussetzung: Raspbian oder vergleichbare Distribution installiert

Methode 1: update-rc.d

Das Starten eines Programms als sogenannter Dienst über ein Runlevel ist die saubere Lösung. Hierzu legt man ein Start-/Stop-Script im Verzeichnis /etc/init.d/ an, in dem Methoden wie start, stop, restart oder auch status definiert werden. Der Vorteil liegt drain, dass diese Vorgehensweise übersichtlich ist, man das Script auch nach dem Start des Raspberry Pis benutzen und damit die Instanz des Programms entsprechend steuern kann.

Step 1

Zunächst benötigen wir ein Start-/Stop-Script. Für viele Programme gibt es seitens der Entwickler bereits ein solches, das bei Paketen meist automatisch im Ordner /etc/init.d/ angelegt wird oder, falls manuell installiert, sich in der Dokumentation des Projektes befindet. Gibt es ein solches Script noch nicht, muss man dieses selbst schreiben.

Dazu legen wir eine Datei mit unserem Wunschnamen im Verzeichnis /etc/init.d/ an. Im Beispiel nenne ich das Script skeleton, dessen Startscript ich als Vorlage nehme. Jedes Startscript beginnt mit dem Shebang, der definiert in welcher Sprache es geschrieben wurde. Darauf folgt ein Kopfteil als Kommentar in dem angegeben werden sollte für welches Programm das Script ist (Provides), mögliche Abhängigkeiten (Required-Start, Required-Stop), das Runlevel (Default-Start, Default-Stop; Voreinstellung sollte im Normalfall passend sein) wie auch eine kurze (Short-Description) und eine lange Beschreibung (Description) über die Funktionalität des Scripts. Daraufhin folgen die Aktionen in einer sogenannten switch-case-Anweisung. Hier sind # START, # STOP, # RESTART ggf. usw. durch die entsprechenden Kommandos zu ersetzen, die das Programm starten, stoppen bzw. neustarten.

In dem Editor nano kann man mittels STRG + X, Y und Enter speichern.

sudo nano /etc/init.d/skeleton

Step 2

Nun müssen wir der Datei noch die Rechte zum Ausführen zuweisen. Dies können wir mit folgendem Befehl machen (skeleton durch Name der Datei ersetzen).

sudo chmod +x /etc/init.d/skeleton

Step 3

Jetzt können wir update-rc.d anweisen das Start-/Stop-Script automatisch in den zuvor definierten Runlevels zu starten und damit auch beim Systemstart.

sudo update-rc.d skeleton defaults

Step 4

Falls wir im laufenden Betrieb das Start-/Stop-Script manuell verwenden möchten, müssen wir das Script gefolgt von dem entsprechenden Funktionsnamen ausführen. Für das Beispielscript ergäben sich folgende Möglichkeiten.

sudo /etc/init.d/skeleton start
sudo /etc/init.d/skeleton stop
sudo /etc/init.d/skeleton restart

Methode 2: rc.local

Wenn kein Start-/Stop-Script für die verwendete Software existiert, und dieses nicht unbedingt geschrieben werden soll, kann man auch rc.local verwenden. Diese Datei wird zuletzt im Runlevel-System ausgeführt. Das bietet den Vorteil, dass abhängige Anwendungen (bspw. Webserver), die ein Start-/Stop-Script besitzen, bereits mit Gewissheit ausgeführt sind und somit die in rc.local eingetragenen Anwendungen problemlos starten.

Step 1

Wir müssen die Datei rc.local mit einem Editor bearbeiten und an deren Ende, jedoch vor exit 0, in der Reihenfolge in der die Anwendungen gestartet werden sollen, deren Startbefehle eintragen. Dabei sollte man mittels su definieren unter welchem Benutzer der Befehl ausgeführt werden soll. Im Beispiel soll der Startbefehl, der über den Parameter -c übergeben wird, von Seafile unter dem Benutzer seafile ausgeführt werden.

sudo nano /etc/rc.local

am Ende der Datei jedoch vor folgender Zeile einfügen

Methode 3: Cron

Der Dienst Cron lässt ein Script zu einer definierten Zeit automatisch ausführen. In unserem Fall lassen wir beim Start des Raspberry Pis (@reboot geschrieben) das gewünschte Script durchstarten. Hier empfiehlt es sich häufig das Programm screen zu verwenden, welches den ausgeführten Prozess laufenlassen kann, auch wenn man nicht mehr eingeloggt ist bzw. in unserem Fall der Aufruf durch Cron eigentlich schon beendet ist. Bei dieser Methode werden, im Gegensatz zum rc.local, nicht (unbedingt) auf Abhängigkeiten aus dem Runlevel-System gewartet.

Step 1

Mittels folgendem Befehl können wir die Cron Datei des Benutzers (mittels sudo vom User root; auch Crontab genannt) abändern. Dort tragen wir am Ende der Datei in eine neue Zeile zunächst den Zeitpunkt und dann den Befehl zum Starten ein. Im Beispiel starten wir das Programm unter /usr/bin/test

sudo crontab -e

Falls das Programm nach dem Aufruf nicht als Daemon weiterlaufen sollte, kann man die Instanz in eine Instanz von screen legen. Dabei sollte man der screen-Instanz einen eindeutigen Namen geben.

Step 2 (optional)

Damit die Variante mit screen funktioniert, muss dieses Programm installiert sein. Wenn dem noch nicht der Fall sein sollte, kann man es über den Paketmanager APT mittels folgenden Befehls installieren.

sudo apt-get install screen

So einfach ist es, in Debian Linux ein Programm automatisch zu starten. Dank der Parameter für update-rc.d oder in vereinfachter Form mit der Stelle an der rc.local ausgeführt wird, ist es auch möglich die Programme unter bestimmten Voraussetzungen zu starten und dabei Probleme durch Abhängigkeiten zu verhindern.

Dieses Tutorial wurde am 22. Februar 2015 überarbeitet.

Dir hat der Artikel gefallen?
Teile ihn mit deinen Freunden!
30 Antworten
  1. Stefan Hoffmann says:

    Hallo Jan,

    hatte mich bereits mal an der Geschichte mit dem Cronjob versucht und war gescheitert. Umso erfreulicher, deinen Artikel mit einer weiteren Methode hier zu lesen. Leider habe ich es nicht hinbekommen, meine Programmierkenntnisse sind dann doch ehr begrenzt. In Variante 1 habe ich in der skeleton Datei (bzw. einer Kopie davon) einfach „start /home/seafile/seafile-server-3.0.4/seafile.sh start“ geschrieben, scheint aber nicht zu reichen und das ganze in der update-rc.d wie beschrieben registriert, kein Webinterface da nach Reboot 🙁 Dann bin ich wieder bei Methode 2 gelandet 🙂 und habe im crontab die Zeile „@reboot screen -dmS NameOfScreenSession /home/seafile/seafile-server-3.0.4/seafile.sh start“ ergänzt und das screen nachinstalliert. Hat auch nicht gefunzt, kannst du mir weiterhelfen? LG, Stefan

    Antworten
  2. Tom says:

    Geht auch super über die /etc/rc.local , hierbei muss dann nicht auf Abhängigkeiten gewartet werden.

    Antworten
  3. André Röcklebe says:

    Hallo Jan, habe für folgendes keine Erklärung, Du vielleicht ?
    Wenn ich folgendes script manuell aufrufe, bin ich bei einer CPU-Last von kleiner 0,7% bezüglich dem script:

    count=0
    while :
    do
    #echo „$count“
    echo „$count“ > /home/logdir/impulszaehler.log
    gpio -g wfi 22 rising
    #sleep 1
    (( count++ ))
    done

    Wenn ich dieses aber über die hier genannte Methode 1 oder aber über meine bisher preferierte Methode über die /etc/inittab aufrufe, dann habe ich eine CPU Last bezüglich des scripts von größer 26% ! Keine Ahnung warum…VG, André

    Antworten
  4. sapnho says:

    Hallo Jan, was macht denn das Screen Programm und hat es irgendwelche Nachteile im Hinsicht auf z.B. CPU Last oder Speicher?

    Antworten
    • Jan Karres says:

      Ich erlaube mir aus er deutschen Debian Package description zu zitieren: „GNU Screen ist ein Terminalmultiplexer, der mehrere separate »Bildschirme« auf einem einzelnen, physischen, zeichenbasierten Terminal darstellt.“

      In dem Fall wird es dazu genutzt, dass das Programm weiter läuft, auch nach dem einmaligen Aufruf. Auf CPU/RAM sollte sich das kaum niederschlagen.

      Antworten
      • sapnho says:

        Eine Frage hierzu hätte ich noch und das „man screen“ hat bestimmt die Lösung, doch ich finde sie einfach nicht.
        Ich habe ein Python Prozess am laufen, dem ich eine Screen zugeordnet habe. Den Prozess beende ich mit „killall python“. Wenn ich aber danach ein neues Python Script aufrufe und wieder mit einer Screen, dann wird mir der Python Prozess nicht angezeigt (ist ein Bildbetrachter) aber bei screen -list wird die screen aufgeführt. Muss ich die speziell in den Vordergrund bringen?

        Antworten
  5. Axel says:

    Sehe ich das richtig, dass man in einer der beschriebenen Weisen ein Regelungsprogramm (Abfrage verschiedener Sensoren, Betätigung einiger Aktoren) dauerhaft laufen lassen könnte, das sich dann beispielsweise nach Stromausfall wieder in Gang setzt?

    Antworten
  6. Sebastian Kinsky says:

    Hallo Jan,

    evtl. könntest du das Tutorial noch etwas ausbauen. Ein Beispiel für die Methode 1 wäre nett. Ich kam über Google auf deinen Blog und hatte eigentlich ein „Muster“-Script erwartet. Vllt. mit Pfadangaben und Argumenten. Das ist für Einsteiger schneller verständlich als das kurze Beispiel oben 😉

    Antworten
    • Jan Karres says:

      Ein Muster Script ist oben vorhanden. Konkrete programmspezifische Anweisungen machen jedoch wenig Sinn, da dies von Anwendung zu Anwendung sehr verschieden sein kann.

      Antworten
  7. schorschifly says:

    Hallo Jan,

    danke für deine tollen Anleitungen, die haben mir schon viel geholfen.
    Ich möchte den RPi gern autonom mit einem UMTS-Stick betreiben. Wenn Strom da ist, soll er Daten aufnehmen und verschicken, solange, bis die Stromversorgung wieder weg ist. Den UMTS-Stick (TP-Link MA260) konnte ich anbinden, der RPi ist online. Dazu führe ich die unten stehenden Befehle aus.
    Die wollte ich jetzt gern in die rc.local schreiben – aber nach einem reboot war der Stick nicht im online-Modus und entsprechend konnte auch keine online-Verbindung hergestellt werden.

    Die zwei Schritte:

    sudo usb_modeswitch -v 2357 -p f000 -V 2357 -P 9000 -W -I -n -M ‚555342431….‘ -2 ‚555342431…‘

    Wenn lsusb dann für den Stick den online-Modus anzeigt (Bus 001 Device 00x: ID 2357:9000 dann:

    sudo wvdial umts

    wobei umts die Verbindungskonfiguration enthält…
    Kann man die zwei Befehle direkt so in die rc.local schreiben? Oder was mache ich falsch?

    Danke schon mal,
    Johannes

    Antworten
  8. Markus G-P says:

    Hallo Jan,

    ich beginne gerade, mit dem RPi umzugehen. Ich habe in crontab versucht, beim Neustart des RPi eine LED zum Blinken zu bekommen (Blinker.py). Das hat funktioniert, ich habe dann die entsprechende Zeile über „sudo crontab -e“ wieder gelöscht. Leider wird Blinker.py dennoch nach dem Neustart ausgeführt und ich finde keine Möglichkeit, das abzustellen. Ich müßte immer killall eingeben. Somit ist mein „GPIO Pin 18“ immer auf Blinkmoudus. Auch deine oben angeführten Methoden haben mich zur Lösung gebracht. Ich finde den Entrag nirgends, der Blinker.py automatsch ausführen läßt. Gerne würde ich Deine Hilfe in Ansruch nehmen. Danke. Makus

    Antworten
  9. H.P.Werner says:

    Hallo Jan
    Ich habe ein Problem mit crontab.Ich möchte ganz einfach Steckdosen schalten.Dazu habe ich ein Script in Python geschrieben.Diese Script funktioniert einwndfrei.Wenn ich es mit crontab starten will geht gar nichts.
    Mein Befehl lautet für einen Test 2 * * * * /etc/init.d/Steckdosen/Schalte.py
    Was ist falsch?Es würde mich freuen wenn du mir helfen könntest.

    Antworten
  10. Thomas says:

    absolut Top Anleitung. Endlich kenne ich die ganzen zusammenhänge. Vielen Dank!!!!!

    Antworten
  11. chaos99oli says:

    muss es nicht ;:
    sudo nano /etc/init.d/rc.local
    sein?

    Antworten
  12. David Gasser says:

    Hallo
    Danke für den super Artikel!
    Ich habe das Script so erstellt wie in Methode 1, und wenn ich es mit /etc/init.d/script start starte macht es auch alles was es soll. (Kleines C Programm das Daten vom Seriellen Port verarbeitet)
    Aber wenn ich reboote, startet das script zwar anscheinend das Programm ( laut $ps axg) aber es macht nichts. Sobald ich aber dann wieder /etc/init.d/script start aufrufe, läuft das Programm doppelt ?!
    Zufällig eine Idee?
    Danke!

    Antworten
  13. Jakob says:

    Hi Jan,
    Vielen Dank für die vielen verschiedenen guten Anleitungen!

    Ich habe nach mehreren Wochen Recherche ein für Laien nicht lösbares Problem:
    Ich möchte (am besten über einen cronjob) folgenden Befehl:

    cd home/pi/GoogleDrive ; ./grive

    automatisch ausführen lassen, und scheitere daran, ihn in eine Schreibweise umzuformulieren die Cronjob tauglich ist. Die Zeile kann ich so wie sie ist ins Terminal eingeben und mein grive wird gesynched.

    Irgendwelche Ideen?

    Liebe Grüße Jakob

    Antworten

Trackbacks & Pingbacks

  1. […] und wie ich finde bessere, Option ist das Schreiben eines Startskriptes wie es auf der Seite jankarres.de beschrieben ist. Dabei ist es nicht zwingend notwendig, dass das Skript alle Aktionen wie Start, […]

  2. […] Link zum Artikel stuffaboutcode Link zum Artikel Jan Karres […]

Antworten

Kommentar verfassen

JanKarres.de © 2007-2017