/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
     |  GGGGGG        CCCCCC      FFFFFFF |
     | G      G      C            F       |
     | G            C             FFFF    |
     | G   GGG      C             FFFF    |
     | G     G       C            F       |
     |  GGGGGG        CCCCCC      F       |
     |                                    |
     |    [G]erman [C]omputer [F]reaks    |
     \            Since 1997             /
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

         Titel: Perl - CGI Einführung
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           By THORIUM :: GCF-Version

Eine Einführung in Perl und CGI Dateien

1. Einleitung
2. Bevor wir loslegen
3. Erstes Perl Script
    3.1 Aufbau
4. Benutzereingaben Perl
    4.1 Aufbau
5. Benutzereingaben CGI
    5.1 Aufbau
6. Datei lesen und schreiben
    6.1 Aufbau

Einleitung

PERL (Practical Extraction and Report Language) ist eine von dem Amerikaner Larry Wall entwickelte Skriptsprache aus dem Unix-Bereich, die aber mittlerweile für fast alle gängigen Platformen zur Verfügung steht (auch Windows und MAC). Perl ist kostenlos erhältlich.

Normalerweise werden Deine Skripte mit geringen oder keinen Änderungen auf allen Platformen lauffähig sein, für die es Perl-Unterstützung gibt, solange keine platformspezifischen Erweiterungen verwendet werden. Wir selbst setzen Perl hauptsächlich auf Windows NT 4.0 Maschinen (Server und Workstation) ein, so dass ein Schwerpunkt auf dieser Platform liegt. In der Regel werden alle auf dieser Website wiedergegebenen Skripte auf allen Platformen laufen. Auf Unterschiede werden wir gegebenenfalls hinweisen.

Perl ist ein universell einsetzbares Werkzeug, mit dem sich Probleme aus den verschiedensten Bereichen lösen lassen: CGI, Webprogrammierung, Netzwerkadministration, Datenbankanbindungen sowie umfangreiche Unterstützung für das Durchsuchen von beliebigen Dateien und Extrahierung von Information aus diesen Dateien (daher der Name "Exraction and Report Language")

Stell Dir vor Du möchtest auf Deinem Windows NT Workstation 4.0 Rechner eine sehr grosse Log-Datei durchsuchen, die Anmelde- und Abmeldezeiten von Unsern protokolliert. Du möchtest gerne wissen, wie oft und wann sich User XY in den letzen drei Wochen an dem Rechner eingeloggt hat und wie lange er durchschnittlich eingeloggt war. Ein Perl-Skript kann die Datei nach dem User XY durchsuchen und Dir die gewünschten Information in übersichtlicher Form präsentieren. Aufgrund der Vielfaltigkeit von Perl erfreut sich diese Sprache wachsender Beliebheit.

 

 

Bevor wir loslegen

Bevor überhaupt mit dem Perlprogrammieren angefangen werden kann brauchen wir einen Server der cgi unterstützt oder wir laden uns eine Perlunterstützung für den lokalen Rechner herunter, der dann aber auch cgi unterstützen muss. Für Unix findet man das auf www.perl.com. Für Windows Systeme geht man auf www.activestate.com. Server die cgi Unterstützung bieten findest du z.B. bei www.kostenlos.de. Einer meiner Lieblingsserver ist z.B. www.portland.co.uk weil er keine Werbung einblendet. Jedoch muss man hier ein anderes Perlverzeichnis angeben. Vielleicht zum anfangen nicht Ideal.

Ich gehe jetzt einmal davon aus das ihr die Servervariante gewählt habt. Wir müssen nun, wenn nicht bereits vorhanden, auf dem Server den Ordner cgi-bin im root Verzeichnis Aufmachen. Da kommen dann später die .cgi und .pl Scripte rein. Nun brauchen wir noch einen Texteditor (von Notepad rate ich ab) und viel Geduld :).

 

 

Erstes kleines Perlscript

#!/usr/bin/perl

# Ein erstes kleines Skript

$z1 = 200;
$z2 = 30;
$result = $z1 + $z2;
$name = "Werner";

print "Content-type: text/html\n\n";
print "<html>\n<head><title>Mein erstes Script</title></head>\n<body>\n";

print "Hallo $name, die Summe von $z1 und $z2 ";
print "ist $result.\n";
print "</body>\n</html>\n";

 

Aufbau

Der Aufbau einer Perl / cgi Datei ist eigentlich recht einfach zu verstehen.

Es mag am Anfang vielleicht etwas Kompliziert wirken, aber im Grunde ist es ganz einfach. Am Anfang jedes Scriptes steht die Zeile #!/usr/bin/perl Diese Zeit dem Unix Server in welchem Verzeichnis sich die Perl Daten befinden um das Script auszuführen. Das ist standardmässig #!/usr/bin/perl Kann aber von Server zu Server verschieden sein. Die Zweite Zeile # Ein erstes kleines Skript ist ein Kommentar. Text nach einem # wird vom Server ignoriert (ausser bei der ersten Zeile). Jeder Befehl wird von einem ; abgeschlossen. Wenn das Script nicht funktioniert erst mal das Kontrollieren.

Die dritte Zeile $z1 = 500; Definiert eine Variable. Was ist nun eine Variable? Nun, Eine Variable ist ganz einfach eine Kiste in die man was reinlegt. Dies können Zahlen oder Buchstaben sein. Man kann mit den Variablen auch Rechnen. Wie in der Zeile $result = $z1 + $z2; Da wird bestimmt, die Kiste 'ergebnis' soll den Inhalt bekommen: Kiste 'z1' und Kiste 'z2'. Das wäre in diesem Beispiel? Richtig... 510. Die letzte Zeile des Blocks $name = "Werner"; füllt nun Buchstaben in die Variablenbox. Um Buchstaben in eine Variable zu geben benutzt man "" oder '' bei ersterem wird z.b. \n in eine Newline umgewandelt und bei zweiterem nicht...

Der Untere Block ist nun die Ausgabe. print "" bedeutet nichts anderes als Sag. Die Rote Zeile muss bei .cgi Scripten dabei stehen da die eine Internetseite wiedergeben. Sollte euch bekannt vor kommen... <html> u.s.w. \n bedeutet Zeilenumsprung. Also wie die Entertaste in einer Textdatei. So kann man die ganze Internetseite auf eine Zeile packen und sie kommt am ende doch schön heraus. Das sollte man aber nicht zu oft / mit zu vielen Daten machen da das Script zu unübersichtlich wird. Wie wir sehen können werden nun die Variablen ausgegeben. Ihr könnt das Script kopieren, in eine .cgi Datei packen und dann auf den cgi-bin Server uploaden und es dann Via Browser ansteuern. Der CHMOD sollte bei 755 liegen.

 

 

Benutzereingaben Perl

#!/usr/bin/perl

# Benutzereingaben

print "Gib bitte Zahl 1 ein: ";
$z1 = <STDIN>;
chomp($z1);

print "Gib bitte Zahl 2 ein: ";
$z2 = <STDIN>;
chomp($z2);

$result = $z1 + $z2;

print "Die Summe von $z1 und $z2 ";
print "ist $result.\n";

Aufbau

Der Aufbau hier ist gleich wie vorher. Nur das hier 2 neue Befehle dazugekommen sind. <STDIN> was die Benutzereingabe verlangt und chomp(). Der aufbau des <STDIN> Befehls ist sehr einfach. Variable = Benutzereingabe, da jedoch die Entertaste auch gespeichert wird, muss diese mit dem Befehl chomp() rausgelöscht werden. Speicher nun den code oben in eine .pl File und führe sie, wenn du auf dem lokalen server ein Perl interpreter hast, mit dem Befehl "Perl datei.pl" aus.

 

 

Benutzereingaben CGI

<html>
<head><title>CGI Benutzereingabe</title></head>
<body>
<form ACTION=../cgi-bin/first.cgi METHOD=Get>
<font face="Verdana" size="2">Zahl 1: <INPUT NAME="z1" TYPE="TEXT" COLS=10 SIZE="10" ALIGN=left>
<br>Zahl 2: <INPUT NAME="z2" TYPE="TEXT" COLS=10 SIZE="10" ALIGN=left></font>
<INPUT TYPE="SUBMIT" VALUE="Senden">
</form>
</body>
</html>


#!/usr/bin/perl

&parse_form;

$result = $in{z1} + $in{z2};

print "Content-type: text/html\n\n";
print "<html>\n<head><title>Rechner</title></head>\n<body><font face=Verdana size=2>";
print "Die Summe von $in{z1} und $in{z2} ist $result.\n";
print "</font>\n</body>\n</html>";

sub parse_form {
    my ($buffer, @pairs, $pair, $name, $value);
    # Read in text
    $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
    if ($ENV{'REQUEST_METHOD'} eq "POST")
    {
        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    }
    else
    {
        $buffer = $ENV{'QUERY_STRING'};
    }
    @pairs = split(/&/, $buffer);
    foreach $pair (@pairs)
    {
        ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        $in{$name} = $value;
    }
}

 

Aufbau

Wie man direkt sehen kann ist das bei CGI schon etwas komplexer :) Natürlich gäbe es eine Kurzform aber das hilft uns dann später nicht weiter weil wir ja Forumulare programmieren wollen. Und das ist unser erstes. So... Der erste blaue Teil ist der code einer HTML Seite. Der zweite Teil in rot der code für das CGI. Den HTML code werde ich nicht erklären da dies zu umfangreich wäre. Aber es gibt ein gutes Tutorial darüber unter http://userpage.fu-berlin.de/~ahahn/www/cgikurs/form.html.

So im CGI code gibt es nun viel neues. Fangen wir oben an. &parse_form; ist ein Verweis auf den 'parse_form' Block. Dieser läuft einmal ab und der Code springt dann wieder rauf und macht da weiter. Der parse_form; Block wird eröffnet mit 'sub name {' und endet mit '}'. Der Inhalt ist ein Standard Code zum auseinandernehmen der Benutzereingaben. Ganz unten sieht man bei $in{$name} = $value; Das alle Benutzereingaben in der Form '$in{Variablename}' gespeichert werden.

Bei $result = $in{1} + $in{2} sieht man, das die Variablen 1 und 2 eben durch $in{} Aufgerufen werden. Wenn man einen anderen Variablennamen haben will muss man einfach die Zeile $in{$name} = $value; abändern. Z.b. in $var{$name} = $value;. Doch das nur nebenbei. Bei dem ausgeben der neuen Internetseite darf im Code kein anderes " vorkommen als das des print "" befehls. Der Rest des Codes sollte eigentlich klar sein. Der Code wird in der Datei 'first.cgi' gespeichert und in das cgi-bin Verzeichnis vom Server kopiert. CHMOD 755.

 

 

Dateien Bearbeiten

<html>
<head><title>CGI Benutzereingabe</title></head>
<body>
<form ACTION=../cgi-bin/first.cgi METHOD=Get>
<font face="Verdana" size="2">Zahl 1: <INPUT NAME="z1" TYPE="TEXT" COLS=10 SIZE="10" ALIGN=left>
<br>Zahl 2: <INPUT NAME="z2" TYPE="TEXT" COLS=10 SIZE="10" ALIGN=left></font>
<INPUT TYPE="SUBMIT" VALUE="Senden">
</form>
</body>
</html>


#!/usr/bin/perl

&parse_form;

$result = $in{z1} + $in{z2};

$pfad = "../ergebnis.txt";
open (DATEI, ">>$pfad");
    print DATEI "$in{z1} + $in{z2} = $result\n";
close(DATEI);

open(DATEI, $pfad);
    @inhalt=<DATEI>;
close(DATEI);


print "Content-type: text/html\n\n";
print "<html>\n<head><title>Rechner</title></head>\n<body><font face=Verdana size=2>";
print "Die Summe von $in{z1} und $in{z2} ist $result.\n";
print "<br>\n<br><h4>Vorherige Rechnungen:</h4>\n";

foreach $zeile (@inhalt) {
    print "$zeile<br>";
}


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

sub parse_form {
    my ($buffer, @pairs, $pair, $name, $value);
    # Read in text
    $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
    if ($ENV{'REQUEST_METHOD'} eq "POST")
    {
        read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    }
    else
    {
        $buffer = $ENV{'QUERY_STRING'};
    }
    @pairs = split(/&/, $buffer);
    foreach $pair (@pairs)
    {
        ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        $in{$name} = $value;
    }
}

 

Aufbau

Jaaa... jetzt sieht das ganze schon richtig gut aus. Der Html code ist gleich geblieben. Aber im Script sind 3 Blocks dazugekommen. open (DATEI, ">>$pfad"); das ist, logischerweise, das öffnen für das schreiben ans ende der Datei. Also die Datei wird nicht überschrieben. Fals das gewünscht wird muss man einfach ein '>' weglassen und die gesammte datei wird überschrieben. Die "" werden hier benötigt was beim öffnen für das lesen einer Datei zu einem Fehler führt! print DATEI ""; das ist der ganz normale print befehl mit der einzigen ausnahme das hier in die DATEI geschrieben wird. Einfach oder? Mit close(DATEI); schliesst man die Datei wieder und der name DATEI wird wieder frei.

Beim lesen einer Datei ist es fast das gleiche. open(DATEI, $pfad); diesmal ohne '>' und ohne "". Bei @inhalt=<DATEI>; muss ich erstmal erklären was Arrays (@) sind. Also, ein Array ist eine kleine Datenbank inder jedem Begriff eine Ordnungszahl zugeordnet wird. Ein Beispiel: @farben = ("rot", "blau", "grün"); Hier wäre die Farbe rot aufzurufen durch $farben[0]. Jep richtig gelesen $. Das heisst ein array ist einfach eine Deffinition verschiedener Variablen die dann untereinander ausgetauscht, verschoben, gelesen und gelöscht werden können.

Der letzte Block gibt den Inhalt der DATEI aus. Dafür wird ein loop verwendet da man ja nicht weiss wieviele zeilen die Datei hat. foreach $zeile (@inhalt) {} damit wird einfach der erste Wert genommen, ihn in $zahlen gespeichert und zum nächsten Eintrag gesprungen. Der Rest sollte eigentlich klar sein. Wenn nicht darf man mir selbstverständlich eine E-Mail schreiben. Auch wenn man andere Fragen zu Perl oder CGI hat: Thorium@gcf.de

 

So das war's für den Anfang. Ein gutes Nachschlagewerk der Befehle wäre ein Buch oder die Internetseite http://www.tekromancer.com/perl/inhalt.html
Demnächst wird ein weiteres Tutorial folgen das beinhalten wird: Wir schreiben unser eigenes Forum o.ä.

by Thorium
Copyright (C) 2001, Thorium
please visit THE GERMAN COMPUTER FREAKS