Entwicklerhandbuch/Boot
Diese Seite ist momentan eine Baustelle im Zustand: 1
-
0
-
1
-
2
-
3
-
4
Programme beim Booten automatisch starten
Es geht hier darum, wie man ein Script bereitstellen kann, sodasss es beim Booten ausgeführt wird. Es geht hier nicht darum, dass es als Dienst (Server) eingerichtet wird. Für diese Anleitung wird folgendes Beispiel gewählt: es soll ein Script beim Booten gestartet werden, welches bei jedem Booten die Bootzeit in ein Logfile schreibt, also ein Logfile aller Bootzeiten erstellt. Ein anderes (naheliegendes) Beispiel wäre ein Script, welches nach jedem Booten die Verbindung zum Internet herstellt.
das eigentliche Script
<source lang="perl">
- !/usr/bin/perl -w
use strict;
my $start = localtime;
open DATEI, ">>", '/var/log/my_logfile' or die "konnte Datei my_logfile nicht oeffnen, $!\n"; print DATEI $start; close DATEI;
__END__ </source>
Dieses Script könnte z.B. unter /usr/sbin/
abgelegt werden. Wenn dieses Script als "my_bootlog.pl"
abgelegt wird, dann wird es mit "/usr/bin/my_bootlog.pl"
aufgerufen werden.
Das Init-Script erstellen (ohne Beachten von insserv)
Dieses Script soll nun durch ein sogenanntes Init-Script aufgerufen werden. "Normalerweise" werden damit Serverdienste gestartet. Deswegen soll ein solches Init-Script (normalerweise) folgende Parameter verstehen:
- start
- stop
- status (gibt den aktuellen Stauts an)
- restart (wenn Dienst nicht läuft, dann starten, sonst stoppen und wieder starten)
- reload (Konfiguration des Dienstes erneut einlesen, ohne den Dienst zu stoppen und neu zu starten)
- force-reload (Konfiguration des Dienstes erneut einlesen, wenn der Dienst dies unterstützt; andernfalls wie restart)
Dazu existiert (bei Arktur) eine Vorlage unter '/etc/init.d/vorlage'
.
Da es hier nicht um einen Server-Dienst geht, sondern um ein Script, welches nur beim Start ausgeführt wird, verwenden wir hier die Vorlage nicht, sondern erstellen ein eigenes Init-Script.
Unser Init-Script soll selbstverständlich beim Aufruf mit dem Parameter 'start' dieses Script starten. Beim Aufruf mit dem Parameter 'stop' soll es den Hinweis ausgeben, dass es nur beim Start einmalig ausgeführt wird und demzufolge nicht gestoppt werden kann. Beim Aufruf des Parameter 'status' soll es hier den letzten Aufruf ausgeben. Die anderen Parameter machen für ein "Einmal-Script" keinen Sinn.
Unser Init-Script my_bootlog (ohne Endung .pl)
<source lang="perl">
- !/usr/bin/perl -w
use strict;
- wir testen, ob das aufzurufende Script da ist, wenn nicht -> Abbruch
unless (-f "/usr/bin/my_script.pl") {
exit
}
- wir werten die Parameter aus
if (scalar @ARGV == 1) {
if ($ARGV[0] eq 'start') { # Parameter 'start' system('/usr/bin/my_script.pl'); print "es wurde ein Eintrag ins Bootlogfile geschrieben\n"; } elsif ($ARGV[0] eq 'stop') { # Parameter 'stop' print "dieses Script wird nur beim Starten ausgeführt und kann nicht gestoppt werden\n"; } elsif ($ARGV[0] eq 'status') { # Parameter 'status' open DATEI, '<', '/var/log/my_logfile' or die "Abbruch, konnte /var/log/my_logfile nicht öffnen\n"; while (my $zeile = <DATEI>) { # wir machen hier nichts, weil wir ja nur die letzte Zeile wollen } close DATEI; print "Status: dieses Script wurde zum letzten Mal um $zeile aufgerufen\n"; } else { print "rufen Sie dieses Script mit den Parameter start | stop | status auf\n"; }
}
__END__ </source>
Delixs arbeitet normalerweise im Runlevel 3. Deshalb muss nun ein symbolischer Link aus dem Verzeichnis '/etc/init.d/rc3.d'
auf das gerade erstellte Script '/etc/init.d/my_bootlog'
und nennen Sie diesen Link 'S25my_bootlog'
. Die Bezeichnung ergibt sich so: S wegen Startscript. Die 25 wurde gewählt, weil es die größte Nummer sein sollte (es wurde hier einfach angenommen, dass alle anderen Nummern kleiner als 25 sind) und my_bootlog, weil dieses (gerade erstellte) Init-Script aufgerufen wird. Die Init-Scripte werden vom Initsystem in der Reihenfolge dieser Nummern abgearbeitet. die größte zu vergebende Nummer ist die 99.
Das Init-Script erstellen (mit Beachten von insserv)
Die Reihenfolge der Init-Scripte ist keineswegs egal, sondern es sind Abhängigkeiten zu beachten. So kann beispielsweise die Verbindung zum Internet nur dann eingeschalten werden, wenn das Netzwerk zur Verfügung steht. Für unser muss verständlicherweise das Filesystem zur Verfügung stehen. Um solche Abhängigkeiten korrekt aufzulösen, wird das Script 'insserv' eingesetzt. Es holt sich aus den Init-Scripten die Informationen und setzt die symbolischen Links so (also neu!), dass diese Abhängigkeiten alle beachtet worden sind.
Dazu muss in den Init-Scripten am Anfang ein "INIT INFO Block"
enthalten sein. Für unser Init-Script würde dieser Block so aussehen:
### BEGIN INIT INFO # Provides: my_bootlog # Required-Start: $remote_fs # Required-Stop: # Default-Start: 3 # Default-Stop: # Description: Schreibt die Bootzeit in das Logfile /var/log/my_logfile ### END INIT INFO
Der Link wird durch insserv
mit folgenden Aufruf gesetzt:
insserv -d /etc/init.d/my_bootlog
- der Parameter -d bedeutet, dass das Script in den angegebenen Runleveln installiert wird
- der Parameter -r entfernt das Script aus allen angegebenen Runleveln
Damit ergibt sich das fertige Init-Script so:
<source lang="perl">
- !/usr/bin/perl -w
- BEGIN INIT INFO
- Provides: my_bootlog
- Required-Start: $remote_fs
- Required-Stop:
- Default-Start: 3
- Default-Stop:
- Description: Schreibt die Bootzeit in das Logfile /var/log/my_logfile
- END INIT INFO
use strict;
- wir testen, ob das aufzurufende Script da ist, wenn nicht -> Abbruch
unless (-f "/usr/bin/my_script.pl") {
exit
}
- wir werten die Parameter aus
if (scalar @ARGV == 1) {
if ($ARGV[0] eq 'start') { # Parameter 'start' system('/usr/bin/my_script.pl'); print "es wurde ein Eintrag ins Bootlogfile geschrieben\n"; } elsif ($ARGV[0] eq 'stop') { # Parameter 'stop' print "dieses Script wird nur beim Starten ausgeführt und kann nicht gestoppt werden\n"; } elsif ($ARGV[0] eq 'status') { # Parameter 'status' open DATEI, '<', '/var/log/my_logfile' or die "Abbruch, konnte /var/log/my_logfile nicht öffnen\n"; while (my $zeile = <DATEI>) { # wir machen hier nichts, weil wir ja nur die letzte Zeile wollen } close DATEI; print "Status: dieses Script wurde zum letzten Mal um $zeile aufgerufen\n"; } else { print "rufen Sie dieses Script mit den Parameter start | stop | status auf\n"; }
}
__END__ </source>