SELFHTML

Funktionen für Betriebssystemaufrufe

Informationsseite

nach unten Allgemeines zu diesen Funktionen
nach unten qx(...) - Andere Programme/Scripts ausführen und STDOUT auffangen
nach unten alarm - SIGALARM in n Sekunden zustellen
nach unten exec - Fremdprogramm aufrufen und eigenen Prozess beenden
nach unten fork - Kindprozess erzeugen
nach unten getpgrp - Prozessgruppe einer Prozessnummer (pid) ermitteln
nach unten getppid - Prozessnummer (pid) des Elternprozesses ermitteln
nach unten getpriority - Priorität eines Prozesses oder Benutzers ermitteln
nach unten kill - Signal an Prozess senden
nach unten pipe - Pipe erzeugen
nach unten setpgrp - Prozessgruppe für Prozess bestimmen
nach unten setpriority - Priorität eines Prozesses oder Benutzers setzen
nach unten sleep - aktuellen Prozess anhalten
nach unten system - Fremdprogramm aufrufen und eigenen Prozess erhalten
nach unten times - Laufzeit des aktuellen Prozesses ermitteln
nach unten wait - auf das Ende eines Kindprozesses warten
nach unten waitpid - auf das Ende eines Kindprozesses mit bestimmter Prozessnummer (pid) warten

 nach unten 

Allgemeines zu diesen Funktionen

Unter "Betriebssystemaufrufe" sind hier Funktionen versammelt, die sich vor allem eng am Konzept der Unix-Betriebssysteme orientieren. Nur wenige der Funktionen sind auf andere Systeme portierbar.

Unix-Systeme verwalten laufende "Programme" in so genannten Prozessen. Jeder Prozess hat eine Prozessnummer (PID). Außerdem gibt es Prozessgruppen. Jeder Prozess gehört zu einer Prozessgruppe. Prozessgruppen haben ebenfalls Nummern. Auch Ihr Perl-Script stellt, wenn es ausgeführt wird, einen solchen Prozess dar, der einer Prozessgruppe angehört. Bei vielen der hier beschriebenen Funktionen können Sie den aktuellen Prozess, also den Ihres Perl-Scripts, durch die "virtuelle" Prozessnummer 0 ansprechen. Über Seite vordefinierte Variablen können Sie jedoch auch die tatsächliche Prozessnummer herausfinden und benutzen. Das folgende Beispielscript zeigt die entsprechenden Variablen im Einsatz:

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
print "Prozessnummer (PID): <b>$$</b><br>\n";
print "Reale Benutzergruppe (GID) des Prozesses: <b>$(</b><br>\n";
print "Effektive Benutzergruppe (GID) des Prozesses: <b>$)</b>\n";
print "</body></html>\n";

Erläuterung:

Mit $$ sprechen Sie die Nummer des aktuellen Prozesses an. Der Prozeß läuft unter einer bestimmten User-ID, die wiederum einer oder mehreren Gruppen angehört. Wenn das Script beispielsweise mit setgid gestartet wurde, enthält die reale Gruppen-ID die Gruppe(n), von der aus gestartet wurde, die effektive Gruppen-ID enthält die Gruppe(n), in die gewechselt wurde (die aktuelle also). Das Beispiel-CGI-Script gibt die entsprechenden Daten aus.

Weitere wichtige Konzepte der Unix-Betriebssysteme, auf die Sie mit Perl-Funktionen Zugriff haben, sind Alarme, Kindprozesse und die so genannten Pipes. Nähere Informationen dazu finden Sie in der Unix-Fachliteratur.

 nach obennach unten 

qx(...) - Andere Programme/Scripts ausführen und STDOUT auffangen

Hierbei handelt es nicht eigentlich nicht um eine Perl-Funktion, sondern um eine besondere Form des Seite Notierens von Zeichenketten. Das qx steht für quoted executable. Die darin eingeschlossene Zeichenkette wird von Perl einfach in einen Kommandozeilenaufruf umgesetzt. Die Standardausgabe des aufgerufenen Kommandos, Fremdprogramms oder Scripts wird aufgefangen und kann in einer Variablen gespeichert werden. Eine andere Möglichkeit, diese Art von ausführbaren Zeichenketten zu notieren, sind die so genannten Backticks. Dabei arbeiten Sie anstelle von qx(irgendein Kommando) mit dem rückwärts gerichteten Accent-Zeichen ` und notieren `irgendein Kommando`.

Die Funktionalität der ausführbaren Zeichenketten ist für CGI-Scripts extrem nützlich, um die Ausgaben anderer Prozesse an den Browser senden zu können. So lassen sich beispielsweise Kapitel XML-Daten mittels Seite XSLT und einem XSLT-Prozessor in HTML übersetzen. Wenn dieser Prozessor seine Ergebnisse auf den Seite Standardausgabekanal STDOUT schreibt, kann das CGI-Script die Ausgabe auffangen und an den Browser senden. Das folgende Beispiel zeigt dies.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
my $Output = qx(/usr/bin/saxon /daten/xml/kunden.xml /daten/xml/kunden.xsl);
print "$Output";

Erläuterung:

Mehr als dieses winzige Script ist nicht nötig, um XML-Daten in HTML-Form an einen aufrufenden Web-Browser zu senden - sofern ein XSLT-Prozessor die Übersetzungsarbeit leistet. Das Beispiel führt folgendes Kommando aus:
/usr/bin/saxon /daten/xml/kunden.xml /daten/xml/kunden.xsl
Dabei ist saxon der Name eines XSLT-Prozessors, also eines ausführbaren Programms. Dieses Programm erwartet im Normalfall zwei Aufrufparameter: erstens die Angabe einer XML-Datei, und zweitens die Angabe einer dazu passenden XSL-Datei mit XSLT-Anweisungen. Saxon übersetzt die XML-Auszeichnungen aufgrund der XSLT-Angaben in HTML-Konstrukte und gibt das Ergebnis, eine vollständige HTML-Datei, auf die Standardausgabe aus. Das Script fängt diese Standardausgabe auf, indem es sie in der Variablen $Output speichert. In dieser Variablen steht also nach dem Saxon-Aufruf der gesamte Inhalt der HTML-Daten. Ein einfacher print-Befehl genügt anschließend, um die gesamten HTML-Daten an den aufrufenden Browser zu senden.

Beachten Sie:

Die Art der Klammerung bei Verwendung von qx ist egal - Sie können auch eckige, geschweifte Klammern oder Schrägstriche verwenden - von letzteren ist allerdings abzuraten, weil viele Kommandos Pfadangaben benötigen und Sie in diesem Fall alle Schrägstriche bei Pfadangaben maskieren müßten.

Bei Pfadangaben sollten Sie auch bei qx(...) stets die einfachen Schrägstriche verwenden - auch wenn das Perl-Script unter Windows/DOS ausgeführt wird.

Mit Backticks würde der Aufruf des obigen Beispiels lauten:
my $Output = `/usr/bin/saxon /daten/xml/kunden.xml /daten/xml/kunden.xsl`;
Um die Backticks zu erzeugen, halten Sie auf den meisten Systemen die Shift-Taste gedrückt, tippen einmal auf die Taste mit den französischen Accent-Zeichen und anschließend die Leertaste.

Im Linkverzeichnis des Online-Angebots von SELFHTML aktuell finden Sie Links zu Seite Linkverzeichnis: XML-Software. Dort finden Sie auch Links zu Produkten wie Saxon.

Die hier beschriebene Möglichkeit ist auf alle Kommandos anwendbar, die etwas auf die Standardausgabe STDOUT schreiben, also z.B. auch auf Betriebssystem-Kommandos wie ls (bzw. dir), oder auch auf andere Perl-Scripts. Einige solcher Programme oder Kommandos schreiben ihren Output bei fehlerhaften Aufrufen jedoch nicht auf STDOUT, sondern auf STDERR. Solche Ausgaben werden von den hier beschriebenen ausführbaren Zeichenketten nicht aufgefangen.

 nach obennach unten 

alarm - SIGALARM in n Sekunden zustellen

Unix-spezifischer Befehl. Bewirkt, dass der Prozess einen SIGALARM nach einer bestimmten Anzahl Sekunden erhält, wenn z.B. ein kritischer Befehl nicht funktioniert.

Erwartet als Parameter:
1. die Anzahl Sekunden, bis der Alarm aktiv wird.

Gibt die Anzahl Sekunden zurück, die verstrichen sind.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body><pre>\n";

eval {
  local $SIG{ALRM} = sub { die "Alarm" };
  alarm(2);
  system("/usr/bin/perl -c /usr/web/myhome/cgi-bin/freelink.pl");
  alarm(0);
};
if ($@ and $@ !~ /Alarm/) {
  print "Problem! 2 Sekunden vergangen!\n";
}
else {
  print "Alles klar!\n";
}
print "</pre></body></html>\n";

Erläuterung:

Das Beispiel zeigt, wie Sie einen "kritischen Systemaufruf" mit Hilfe eines Timeout-Alarms behandeln können. Dazu wird in dem Script zunächst ein für solche Behandlung typischer Seite eval-Block notiert. Darin wird mit der typischen Anweisung:
local $SIG{ALRM} = sub { die "Alarm" };
eine Behandlungsroutine für SIGALARM definiert. Anschließend wird mit alarm(2) ein Timeout von 2 Sekunden definiert, bevor der Alarm aktiv wird. Mit alarm(0) wird der Alarm wieder zurückgesetzt.
Danach wird versucht, mit nach unten system den Perl-Interpreter aufzurufen, und zwar so, dass er ein bestimmtes Script auf Syntax überprüft. Sollte dieser Vorgang mehr als 2 Sekunden dauern, wird der Alarm aktiv.
Mit der Abfrage if ($@ and $@ !~ /Alarm/) wird überrpüft, ob der Alarm aktiv wurde. Wenn ja, wird eine entsprechende Meldung ausgegeben. Im else-Zweig kann der Code stehen, der ausgeführt wird, wenn alles in Ordnung war. Im Beispiel wird einfach ebenfalls eine entsprechende Meldung ausgegeben.

Beachten Sie

Aufrufe mit nach unten system oder nach oben qx(...) in Verbindung mit alarm können zu sogenannten Zombies führen. Möglicherweise müssen Sie sie für solche Zwecke mit Hilfe von nach unten fork und nach unten exec selbst implementieren.

 nach obennach unten 

exec - Fremdprogramm aufrufen und eigenen Prozess beenden

Startet einen anderen Prozess und beendet das aktuelle Script. Der aktuelle Prozess wird dabei durch den neuen Prozess vollständig ersetzt. Wenn Sie das aktuelle Script nicht beenden wollen, benutzen Sie nach unten system, nach oben qx(...) oder Seite open mit dem Pipe-Zeichen |.

Erwartet als Parameter:
1. Kommandozeilenaufruf des gewünschten Programms,
2. bis n. (optional) Liste mit Aufrufparametern.

Beispiel:

#!/usr/bin/perl -w

exec("/usr/bin/perl","mystats.pl") if -e "mystats.pl";

Erläuterung:

Das Beispiel fragt mit Hilfe des Seite Dateitestoperators -e ab, ob eine Datei namens mystats.pl im aktuellen Verzeichnis existiert. Wenn ja, wird der Perl-Interpreter (in einem eigenen, neuen Prozess) gestartet und führt mystats.pl aus.

 nach obennach unten 

fork - Kindprozess erzeugen

Unix-spezifischer Befehl. Erzeugt eine Kopie des aktuellen Prozesses, die dem aktuellen, erzeugenden Prozess untergeordnet ist. Ein Perl-Script kann sich auf diese Weise gabeln (engl. fork) und Daten in zwei getrennten Prozessen verarbeiten. Auf geöffnete Dateien können dabei beide Prozesse zugreifen. Alles übrige, wie Variablen usw., wird vom Elternprozess in den Kindprozess kopiert. Die Variable, die den Rückgabewert von fork speichert, hat jedoch im Elternprozess einen Wert, nämlich die Prozessnummer des Kindprozesses, während sie im Kindprozess den Wert 0 hat.

Erwartet keine Parameter.

Gibt die vom Betriebssystem zugewiesene Prozessnummer des Kindprozesses zurück.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

$| = 1;
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
my $Eltern_pid = $$;
my $Kind_pid = fork();

if($Kind_pid) {
  print "<p>Hier ist der Elternprozess. Der Kindprozess hat die PID <b>$Kind_pid</b></p>\n";
  wait;
}
else {
  my $Eltern_pid = getppid();
  print "<p>Hier ist der Kindprozess. Der Elternprozess hat die PID <b>$Eltern_pid</b></p>\n";
  exit(0);
}
print "</body></html>\n";

Erläuterung:

Das Beispiel erzgeut mit fork einen Kindprozess. Der Rückgabewert der Funktion, die Prozessnummer des Kindprozesses, wird in dem Skalar $Kind_pid gespeichert. Im Beispiel ist daraufhin eine if-Abfrage notiert. Mit if($Kind_pid) wird abgefragt, ob der Skalar $Kind_pid einen Wert ungleich 0 hat. Ist das der Fall, werden Anweisungen ausgeführt, die zum Elternprozess gehören. Im Beispiel wird eine Meldung ausgegeben, dass sich das Script im Elternprozess befindet. Außerdem wird die Prozessnummer des Kindprozesses ausgegeben. Danach wird mit der Anweisung nach unten wait gewartet, bis der Kindprozess beendet ist. Im else-Zweig, in den das Script gelangt, wenn Kind_pid den Wert 0 hat, wird dagegen ausgegeben, dass der Kindprozess aktiv ist. Außerdem wird die Prozessnummer des Elternprozesses ausgegeben. Danach wird der Kindprozess mit der Anweisung exit(0); beendet. Der Elternprozess, der darauf nur gewartet hat, gibt dann noch die letzte Zeile HTML-Code aus.
Das besondere Verhalten des Scripts, das in zwei Prozessen läuft, zeigt sich im Beispiel darin, dass sowohl der if-Zweig als auch der else-Zweig ausgeführt werden. Die Erklärung ist, dass die if-Bedingung für den Elternprozess wahr ist, die else-Alternative dagegen für den Kindprozess.

 nach obennach unten 

getpgrp - Prozessgruppe einer Prozessnummer (pid) ermitteln

Unix-spezifischer Befehl.

Erwartet als Parameter:
1. eine Prozessnummer, zu der die zugehörige Prozessgruppe ermittelt werden soll. Um die Prozessgruppe des aktuellen Prozesses zu ermitteln, 0 übergeben.

Gibt die Gruppennummer zurück.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";

my $Gruppennummer = getpgrp(0);
print "Die Prozessgruppe des aktuellen Prozesses ist <b>$Gruppennummer</b>\n";

print "</body></html>\n";

Erläuterung:

Das Beispiel ermittelt die Gruppennummer des aktuellen Prozesses mit getpgrp, sendet HTML-Code an den Browser und gibt die ermittelte Nummer aus.

 nach obennach unten 

getppid - Prozessnummer (pid) des Elternprozesses ermitteln

Unix-spezifischer Befehl.

Erwartet keine Parameter.

Gibt die Prozessnummer (PID) des Elternprozesses des aktuellen Scripts zurück.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";

my $Eltern_pid = getppid();
print "Die PID des Elternprozesses lautet <b>$Eltern_pid</b>\n";

print "</body></html>\n";

Erläuterung:

Das Beispiel ermittelt die PID des Elternprozesses mit getppid, sendet HTML-Code an den Browser und gibt die ermittelte Nummer aus.

 nach obennach unten 

getpriority - Text

Unix-spezifischer Befehl. Ermittelt die aktuelle Priorität eines Prozesses, einer Prozessgruppe oder eines Benutzers. Prozesse mit höherer Priorität erhalten unter den aktuell laufenden Prozessen mehr Systemressourcen zur Ausführung.

Erwartet als Parameter:
1. eine Angabe dazu, ob Sie die Priorität für einen bestimmten Prozess, eine Prozessgruppe oder einen Benutzer ermitteln wollen. Dazu übergeben Sie am besten eine der Konstanten, die in resources.ph definiert sind (siehe unten).
2. die Nummer des Prozesses, der Prozessgruppe oder des Benutzers.

Gibt die Priorität des Prozesses, der Prozessgruppe oder des Benutuzers als Zahl zurück. Der mögliche Wertebereich ist abhängig vom System.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";

require "resource.ph";
my $Prio = getpriority(&PRIO_PROCESS,0);
print "Prioritaet des aktuellen Prozesses: $Prio\n";

print "</body></html>\n";

Erläuterung:

Das Beispiel ermittelt mit getpriority die Priorität des aktuellen Prozesses und gibt diese aus. Dazu wird mit require "resource.ph" die Kopfdatei eingebunden, die die Definition der Konstanten folgenden enthält:

Konstante: Bedeutung:
PRIO_PROCESS Die Priorität eines bestimmten Prozesses ermitteln, dessen Prozessnummer (oder 0 für den aktuellen Prozess) im zweiten Parameter von getpriority angegeben wird.
PRIO_PGRP Die Priorität einer Prozessgruppe ermitteln, deren Nummer (oder 0 für die aktuelle Prozessgruppe) im zweiten Parameter angegeben wird.
PRIO_USER Die Priorität eines Benutzers ermitteln, dessen Benutzernummer (UID - oder 0 für den aktuelle Benutzer) im zweiten Parameter angegeben wird.

Durch Voranstellen eines &-Zeichens können Sie eine der Konstanten wie im Beispiel gezeigt als ersten Parameter übergeben.

Beachten Sie:

Diese Funktion führt zu einem schweren Fehler, wenn das System keine Prozess- bzw. Benutzerverwaltung im Sinne von Unix kennt.

 nach obennach unten 

kill - Signal an Prozess senden

Unix-spezifischer Befehl. Damit können Sie aus einem Perl-Script heraus Signale an andere, laufende Prozesse auf dem Rechner senden und diese dadurch beeinflussen. Interessant ist dies vor allem, wenn Sie in Ihrem Perl-Script eigene Kindprozesse erzeugen (siehe nach oben fork). Eltern- und Kindprozess können dann durch Signale kommunizieren.

Erwartet als Parameter:
1. Nummer oder Name einer Konstante (siehe Tabelle weiter unten) des gewünschten Signals (oder 0 übergeben, um herauszufinden, ob der Prozess mit der nachfolgend übergebenenen Prozessnummer noch "am Leben" ist),
2. bis n. einer oder mehrere Prozesse, an die das Signal gesendet werden soll.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

$| = 1;
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";

my $Kind_pid = fork();

if(kill(0,$Kind_pid)) {
  print "<p>Hier meldet sich ein Prozess</p>\n";
  kill("KILL",$Kind_pid);
}
print "</body></html>\n";

Erläuterung:

Das Beispiel erzeugt mit nach oben fork einen Kindprozess. Mit if(kill(0,$Kind_pid)) wird abgefragt, ob dieser Prozess am Leben ist. Wenn ja, wird ausgegeben, dass sich ein Prozess meldet. Da im Beispiel für den Kindprozess kein eigenener Perl-Code notiert ist und Kindprozesse einfach erst mal alles vom Elternprozess kopieren, würden beide Prozesse sich melden und Hier meldet sich ein Prozess ausgeben. Doch im Beispiel wird das verhindert, indem der Elternprozess den Kindprozess mit kill("KILL",$Kind_pid) tötet, bevor dieser die Anweisung mit der Ausgabe der Meldung ausführen kann. Die Meldung wird also insgesamt nur einmal ausgegeben.

Die folgende Tabelle enthält typische Signale mit Name, wie Sie sie als ersten Parameter an kill übergeben können. Eine Garantie, dass alle hier aufgelisteten Signale auf jedem Rechner in Perl funktionieren, besteht nicht. Auch die entsprechenden Nummern wurden hier weggelassen, da sie von System zu System schwanken können. Maßgeblich ist letztendlich immer, was auf dem jeweiligen Rechner in der Datei /usr/include/signal.h definiert ist.

Name: Bedeutung:
"HUP" Ereignis: Verbindung beendet
"INT" Ereignis: allgemeine Unterbrechung
"QUIT" Ereignis: Endekennzeichen
"ILL" Anweisung ist illegal
"TRAP" Anweisung ist eine "Falle"
"ABRT" Abbruch
"FPE" Fehler bei Fließkommabrechnung
"KILL" Prozess "abschießen" (Unix: kill -9)
"BUS" Bus-Übertragungsfehler
"SEGV" Segment-Schutzverletzung im Speicher
"PIPE" Fehler bei Pipe-Kommunikation
"ALARM" Allgemeiner Alarm
"TERM" Beendigung
"USR1" Benutzerdefiniert 1
"USR2" Benutzerdefiniert 2
"CHLD" Signal vom Kindprozess
"PWR" Stromausfall
"WINCH" Fenstergröße wurde von einem HintergrundProzess geändert
"URG" Dringende Bedingung
"IO" Asynchronische Ein-/Ausgabe
"STOP" Prozess anhalten
"TSTP" Prozess vom Terminal aus anhalten
"CONT" Angehaltenen Prozess fortführen
"TTIN" Prozess anhalten durch Lesen vom kontrollierenden Terminal
"TTOU" Prozess anhalten durch Schreiben auf kontrollierendes Terminal
"VTALARM" Virtueller Zeittaktgeber abgelaufen
"PROF" Profil-Zeittaktgeber abgelaufen
"XCPU" CPU-Belastungsgrenze erreicht
"XSFZ" Dateigrößengrenze erreicht

Beachten Sie:

Mit dem folgenden Script können Sie abfragen, welche Signale unter welchen Signalnummern auf Ihrem Server-Rechner konfiguriert sind:

#!/usr/bin/perl

use Config;

defined $Config{sig_name} || die "Kein Konfigmodul?";
foreach $name (split(' ', $Config{sig_name})) {
  $i++;
  printf "%3d) %s \t", $i, $name;
  if (($i % 5) == 0) { print "\n";  }
}
print "\n";

 
 nach obennach unten 

pipe - Pipe erzeugen

Unix-spezifischer Befehl. Ermöglicht zwei Prozessen, miteinander zu kommunizieren. Eine "Pipe" (Pfeife, Röhre) ist dabei der Kommunikationskanal für die beiden Prozesse. Es gibt einen Kanal zum Schreiben von Daten und einen zum Lesen von Daten. Für beide Kanäle gibt es jeweils ein "Handle". Diese Lese- und Schreib-Handles sind ganz ähnlich den Seite Datei-Handles. Typischerweise wird eine Pipe eröffnet, bevor mit nach oben fork ein Kindprozess erzeugt wird. Eltern- und Kindprozess können dann über die geöffnete Pipe Daten austauschen.

Erwartet als Parameter:
1. den Namen eines Lese-Handles (frei vergebbar),
2. den Namen eines Schreib-Handles (frei vergebbar)

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

$| = 1;
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body><pre>\n";

pipe(LESE_HANDLE, SCHREIB_HANDLE);
my $Kind_pid = fork();

if ($Kind_pid) {
 close(LESE_HANDLE);
 my $old_handle = select(SCHREIB_HANDLE);
 $| = 1;
 for (my $i=1;$i<=5;$i++) {
   sleep(1);
   print SCHREIB_HANDLE "$i (gesendet vom Elternprozess)\n";
 }
 close(SCHREIB_HANDLE);
 wait;
 select($old_handle);
}
else {
 close(SCHREIB_HANDLE);
my $Speicher;
 while(defined($Speicher = <LESE_HANDLE>)) {
   print "Empfangen: $Speicher \n";
 }
 exit(0);
}
print "</pre></body></html>\n";

Erläuterung:

Das Beispiel erzeugt mit pipe eine Pipe. Über die beiden übergebenen Handle-Namen LESE_HANDLE und SCHREIB_HANDLE ist anschließend der Nachrichtenaustausch zwischen zwei Prozessen möglich. Mit Hilfe von nach oben fork erzeugt das Script einen Kindprozess. Der Elternprozess läuft im if-Zweig des nachfolgenden Codes, der Kindprozess im else-Zweig. Beim Erzeugen des Kindprozesses wird alles kopiert - außer die beiden Handles aus der Pipe. Diese werden nicht kopiert, bleiben allerdings für beide Prozesse verfügbar. Deshalb muss jeder Prozess erst mal das nicht benötigte Handle mit Seite close schließen. Um die Pufferung der Daten abschalten zu können, muss im if-Zweig außerdem mit Seite select das Schreib-Handle ausgewählt werden. Alle Anweisungen sowohl des if- als auch des else-Zweiges werden insgesamt fünf mal ausgeführt. Denn in einer Seite for-Schleife, die von 1 bis 5 zählt, schreibt der Elternprozess, nachdem er zu Testzwecken eine Sekunde lang anhält (siehe nach unten sleep), den aktuellen Zählerstand in das Schreib-Handle. Der Kindprozess im else-Zweig kann diese Daten lesen, indem er eine Seite while-Schleife verwendet und darin das Lese-Handle ausliest. Zur Kontrolle gibt der Kindprozess aus, was er eingelesen hat.

 nach obennach unten 

setpgrp - Prozessgruppe für Prozess bestimmen

Unix-spezifischer Befehl. Ordnet einen Prozess einer Prozessgruppe zu.

Erwartet als Parameter:
1. die Prozessnummer (PID) des gewünschten Prozesses (0 für aktuellen Prozess übergeben),
2. die Nummer der Prozessgruppe, der dieser Prozess zugeordnet werden soll (0 für aktuelle Prozessgruppe übergeben).

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
my $gruppe_alt = getpgrp(0);
print "Prozessgruppe alt: <b>$gruppe_alt</b><br>\n";

setpgrp(0,0);

my $gruppe_neu = getpgrp(0);
print "Prozessgruppe neu: <b>$gruppe_neu</b>\n";

print "</body></html>\n";

Erläuterung:

Das Beispiel ordnet den aktuellen Prozess der aktuellen Prozessgruppe zu und erzeugt so seine eigene Prozeßgruppe. Zum Vergleich wird die aktuelle Prozeßgruppe vorher und hinterher ausgelesen und jeweils ausgegeben.

 nach obennach unten 

setpriority - Priorität eines Prozesses oder Benutzers setzen

Unix-spezifischer Befehl. Setzt die aktuelle Priorität eines Prozesses, einer Prozessgruppe oder eines Benutzers. Prozesse mit höherer Priorität erhalten unter den aktuell laufenden Prozessen mehr Systemressourcen zur Ausführung.
Da diese Funktion "systemkritisch" ist, steht sie auf den meisten Unix-Systemen nur Benutzern mit root-Kennung zur Verfügung.

Parameter wie bei nach oben getpriority

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";

require "resource.ph";
my $Prio = getpriority(&PRIO_PROCESS,0);
$Prio += 1;
setpriority (&PRIO_PROCESS, 0, $Prio);
print "Neue Prioritaet des aktuellen Prozesses: $Prio\n";

print "</body></html>\n";

Erläuterung:

Das Beispiel liest mit getpriority die Priorität des aktuellen Prozesses ein, erhöht sie anschließend um 1 und setzt dann mit setpriority den neuen Wert. Zur Kontrolle gibt das Script den aktuellen Wert der Priorität aus.

Beachten Sie:

Diese Funktion führt zu einem schweren Fehler, wenn das System keine Prozess- bzw. Benutzerverwaltung im Sinne von Unix kennt.

 nach obennach unten 

sleep - aktuellen Prozess anhalten

Hält die Ausführung des Scripts für eine bestimmte Anzahl Sekunden an und fährt dann fort.

Erwartet als Parameter:
1. die Anzahl Sekunden, die angehalten werden soll. Wenn nichts übergeben wird, wird "für ewig" angehalten.

Beispiel:

#!/usr/bin/perl -w

use strict;

sleep(10);
exec("/usr/bin/perl","aufwachen.pl");

Erläuterung:

Das Beispiel wartet durch Aufruf von sleep(10) 10 Sekunden und führt dann mit nach oben exec ein anderes Script aus.

 nach obennach unten 

system - Fremdprogramm aufrufen und eigenen Prozess erhalten

Ruft ein anderes Programm aus und ermittelt dessen Rückgabewert. Wenn Sie daran interessiert sind, welche Ausgaben das andere Programm erzeugt, sollten Sie die Funktion Seite open mit dem Zeichen | oder nach oben qx(...) bzw. `...` (Backticks) benutzen.

Erwartet als Parameter:
1. eine Zeichenkette oder eine Liste. Werden mehrere Parameter, also eine Liste, übergeben, wird der erste Parameter als das auszuführende Programm bzw. Kommando interpretiert, und die übrigen Parameter als Übergabeparameter für das Programm bzw. Kommando.

Gibt den Rückgabewert des ausgeführten Programms oder Kommandos zurück.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

(my $Datei_1, my $Datei_2) = split(/&/,$ENV{'QUERY_STRING'});
my $Pfaddatei_1 = "/usr/web/daten/alt/".$Datei_1;
my $Pfaddatei_2 = "/usr/web/daten/neu/".$Datei_2;
my $Vergleich = system("cmp $Pfaddatei_1 $Pfaddatei_2 >/dev/null");

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Test-Ausgabe</title></head><body>\n";
if($Vergleich == 0) {
  print "<tt>$Pfaddatei_1</tt><br>und<br><tt>$Pfaddatei_2</tt><br><b>sind gleich!</b>!\n";
}
else {
  print "<tt>$Pfaddatei_1</tt><br>und<br><tt>$Pfaddatei_2</tt><br><b>sind verschieden!</b>!\n";
}
print "</body></html>\n";

Erläuterung:

Das Beispielscript ermittelt den Inhalt der Seite CGI-Umgebungsvariablen QUERY_STRING, erwartet in dem übergebenen Parameter ein kaufmännisches Und (&) und trennt den Teil davor und den dahinter in die Skalare $Datei_1 und $Datei_2. Die beiden Daten werden als Dateien interpretiert. Ein Beispielaufruf des Scripts könnte lauten:
/cgi-bin/script.pl?news.htm&news.htm
Das Script hängt die beiden gleichnamigen Dateien an unterschiedliche Pfadnamen auf dem Server und erzeugt damit zwei unterschiedliche Dateipfadangaben in den Skalaren $Pfaddatei_1 und $Pfaddatei_2. Mit system wird nun der Shell-Befehl cmp (unter Unix) gestartet, der zwei Dateien daraufhin überprüft, ob sie gleich sind. Dem Befehl werden die beiden Skalare mit den Pfadangaben übergeben. Eine Ausgabe soll der Befehl in diesem Fall nicht erzeugen. Deshalb wird seine Ausgabe nach /dev/null umgeleitet. Der Rückgabewert des system-Aufrufs und damit des cmp-Befehls wird jedoch gespeichert, nämlich im Skalar $Vergleich. Wenn der Wert 0 ist, sind die verglichenen Dateien gleich, andernfalls unterschiedlich. Diese Information wird an den aufrufenden Browser zurückgegeben.

 nach obennach unten 

times - Laufzeit des aktuellen Prozesses ermitteln

Ermittelt die Laufzeit eines Prozesses (und, wenn vorhanden, seiner Kindprozesse) von der Erzeugung bis zum Ausführen dieses times-Aufrufs. Ermittelt werden für jeden Prozess jeweils zwei Werte: "user time" und "system time". Während "user time" bezeichnet, wie lange der Prozess selber gelaufen ist, gibt "system time" die Zeit an, wie lange der Prozess das Betriebssystem beschäftigt hat. Die Summe beider Zeiten ist die gesamte verbrauchte CPU-Zeit.
Die gemessenen Zeiten basieren auf so genannten Uhrenticks. Die Anzahl der Uhrenticks pro Sekunde ist auf Unix-Systemen einstellbar (TICKSPERSEC in der Datei conf.h).

Erwartet keine Parameter.

Gibt eine Liste mit Laufzeiten in Sekunden (Fließkommazahlen, mit Angaben zu Sekundenbruchteilen) zurück. Schema:
($user_time,$system_time[,$user_time_Kind,$system_time_Kind,...])

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

my $x;
for(my $i = 0; $i < 1000; $i++) {
  for(my $k = 0; $k < 100; $k++) {
    $x = $i * $k / time();
  }
}

my ($Systemzeit, $Userzeit) = times();
my $CPU_Zeit = $Systemzeit + $Userzeit;

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
print "verbrauchte Systemzeit: <b>$Systemzeit</b> Sekunden<br>\n";
print "verbrauchte Userzeit: <b>$Userzeit</b> Sekunden<br>\n";
print "verbrauchte CPU-Zeit: <b>$CPU_Zeit</b> Sekunden\n";
print "</body></html>\n";

Erläuterung:

Das Beispiel enthält zwei verschachtelte Seite for-Schleifen, in denen sehr viel zu rechnen ist (es werden insgesamt 100.000 Funktionsaufrufe von Seite time und Bruchzahlrechnungen durchgeführt). Anschließend ermittelt das Beispiel die benötigten Zeiten. Vom Aufruf der Funktion times werden die ersten beiden Listenelemente, also die für den aktuellen Prozess, in den Skalaren $Systemzeit und $Userzeit festgehalten. Aus der Summe dieser beiden wird noch die CPU-Zeit ermittelt und in $CPU_Zeit gespeichert. Zur Kontrolle gibt das Script die ermittelten Zeiten aus.

 nach obennach unten 

wait - auf das Ende eines Kindprozesses warten

Unix-spezifischer Befehl.

Erwartet keine Parameter.

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

#use strict;
use CGI::Carp qw(fatalsToBrowser);

$| = 1;
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
my $Kind_pid = fork();

if($Kind_pid) {
  print "<p>Hier ist der Elternprozess.</p>\n";
  wait();
  print "<p>Der Kindprozess ist zuende.</p>\n";
}
else {
  print "<p>Hier ist der Kindprozess.</p>\n";
  exit(0);
}
print "</body></html>\n";

Erläuterung:

Das Beispiel erzgeut mit nach oben fork einen Kindprozess. Mit if($Kind_pid) wird abgefragt, ob der Skalar $Kind_pid einen Wert ungleich 0 hat. Ist das der Fall, werden Anweisungen ausgeführt, die zum Elternprozess gehören. Im Beispiel wird eine Meldung ausgegeben, dass sich das Script im Elternprozess befindet. Im else-Zweig, in den das Script gelangt, wenn Kind_pid den Wert 0 hat, wird dagegen ausgegeben, dass der Kindprozess aktiv ist.
Normalerweise würde erst der if-Zweig abgearbeitet, dann der else-Zweig. Durch die Anweisung wait() im if-Zweig jedoch wartet der Elternprozess auf das Ende des Kindprozesses, bevor er fortfährt. So wird vorher der else-Zweig abgearbeitet, und anschließend die letzte Meldung im if-Zweig ausgegeben.

 nach obennach unten 

waitpid - auf das Ende eines Kindprozesses mit bestimmter Prozessnummer (pid) warten

Unix-spezifischer Befehl. Ruft im Gegensatz zu nach oben wait direkt das Betriebssystem auf.

Erwartet als Parameter:
1. Die Prozessnummer (PID) des gewünschten Kindprozesses.
2. Schalter (Flags - siehe Tabelle weiter unten)

Gibt die Prozessnummer (PID) des beendeten Prozesses zurück, oder -1, wenn der gewünschte Kindprozess nicht oder nicht mehr existiert. Auf manchen Systemen ist auch der Rückgabewert 0 möglich - er bedeutet, dass der Kindprozess noch immer läuft (d.h. ein Timeout beim Warten überschritten wurde).

Beispiel eines vollständigen CGI-Scripts in Perl:

#!/usr/bin/perl -w

#use strict;
use CGI::Carp qw(fatalsToBrowser);
use POSIX;

$| = 1;
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
my $Kind_pid = fork();

if($Kind_pid) {
  print "<p>Hier ist der Elternprozess.</p>\n";

  use POSIX ":sys_wait_h";
  do {
    my $Kind_pid = waitpid(-1,&WNOHANG);
  } until $Kind_pid == -1;

  print "<p>Der Kindprozess ist zuende.</p>\n";
}
else {
  print "<p>Hier ist der Kindprozess.</p>\n";
  exit(0);
}
print "</body></html>\n";

Erläuterung:

Das Beispiel tut das gleiche wie jenes bei nach oben wait. In diesem Fall wird jedoch mit einer Seite do-until-Schleife gewartet, bis der Kindprozess zuende ist. Das ist der Fall, wenn die Funktion waitpid den Rückgabewert -1 liefert, der Kindprozess also nicht mehr existiert.

Der Funktion waitpid wird im Beispiel das Flag &WNOHANG übergeben. Die Konstanten dazu werden im Seite Standardmodul POSIX definiert. Daher ist es erforderlich, dieses Modul so wie im Beispiel mit use POSIX ":sys_wait_h" einzubinden.
Die folgende Tabelle listet die Flags auf, die Sie an der Stelle übergeben können.

Flag: Bedeutung:
&WEXITSTATUS Enthält den Rückgabewert des Kindprozesses (genauer: die untersten 8 Bit, also einen Wert bis maximal 255).
&WIFEXITED Hat den Wert true oder 1, wenn der Kindprozess normal beendet wurde.
&WIFSIGNALED Hat den Wert true oder 1, wenn der Kindprozess durch ein unbeantwortetes Signal beendet wurde.
&WIFSTOPPED Hat den Wert true oder 1, wenn der Kindprozess angehalten wurde.
&WNOHANG Der aufrufende Prozess wird nicht blockiert, falls der Kindprozess nicht sofort reagiert. In einem solchen Fall wird waitpid() sofort beendet und liefert 0 zurück.
&WSTOPSIG Die Nummer des Signals, das zum Anhalten des Kindprozesses führte (das Anhalten des Kindprozesses kann mit &WIFSTOPPED ermittelt werden.
&WTERMSIG Die Nummer des Signals, das vom Kindprozess nicht beantwortet wurde und deshalb zu dessen Beenden führte (ob dies der Fall ist, kann mit &WIFSIGNALED ermittelt werden.
&WUNTRACED waitpid() kehrt mit dem Status eines bereits gestoppten Kindprozesses zurück, dessen exit-Rückgabewert aber noch nicht abgefragt wurde.

 
 nach oben
weiter Seite Funktionen für Informationen aus Konfigurationsdateien
zurück Seite Funktionen für Datei- und Verzeichnismanagement
 

© 2001 E-Mail selfhtml@teamone.de