Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Einleitung
TEIL I: Einstieg in Linux
2 Die Installation
3 Erste Schritte
4 Linux als Workstation für Einsteiger
TEIL II: Grundlagen
5 Kernel
6 Grundlagen aus Anwendersicht
TEIL III: Die Shell
7 Die Shell
8 Reguläre Ausdrücke
9 Konsolentools
10 Die Editoren
11 Shellskriptprogrammierung mit der bash
12 Die C-Shell
TEIL IV: System- & Netzwerkadministration
13 Benutzerverwaltung
14 Grundlegende Verwaltungsaufgaben
15 Netzwerkgrundlagen
16 Anwendersoftware für das Netzwerk
17 Netzwerkdienste
18 Mailserver unter Linux
19 LAMP & Co.
20 DNS-Server
21 Secure Shell
TEIL V: Die grafische Oberfläche
22 Die grafische Oberfläche
23 Window-Manager und Desktops
24 X11-Programme
25 Multimedia und Spiele
TEIL VI: Systeminterna
26 Prozesse und IPC
27 Bootstrap und Shutdown
28 Dateisysteme
29 Virtualisierung und Emulatoren
TEIL VII: Programmierung und Sicherheit
30 Softwareentwicklung
31 Crashkurs in C und Perl
32 Einführung in Computersicherheit
33 Netzwerksicherheit überwachen
TEIL VIII: Anhang
A Lösungen zu den einzelnen Aufgaben
B Kommandoreferenz
C X11-InputDevices
D MBR
E Buch-DVDs
F Glossar
G Literatur
Stichwort
Ihre Meinung?

Spacer
Linux von Johannes Plötner, Steffen Wendzel
Das umfassende Handbuch
Buch: Linux

Linux
Rheinwerk Computing
1282 S., 5., aktualisierte Auflage 2012, geb., mit 2 DVDs
49,90 Euro, ISBN 978-3-8362-1822-1
Pfeil 31 Crashkurs in C und Perl
Pfeil 31.1 Die Programmiersprache C – ein Crashkurs
Pfeil 31.1.1 Hello, World in C
Pfeil 31.1.2 Kommentare
Pfeil 31.1.3 Datentypen und Variablen
Pfeil 31.1.4 Operatoren
Pfeil 31.1.5 Bedingte Anweisungen
Pfeil 31.1.6 Schleifen
Pfeil 31.1.7 Funktionen
Pfeil 31.1.8 Präprozessor-Direktiven
Pfeil 31.1.9 Zeiger-Grundlagen
Pfeil 31.1.10 Array-Grundlagen
Pfeil 31.1.11 Strukturen
Pfeil 31.1.12 Arbeiten mit Zeichenketten (Strings)
Pfeil 31.1.13 Einlesen von Daten
Pfeil 31.1.14 FILE und das Arbeiten mit Dateien
Pfeil 31.1.15 Das war noch nicht alles!
Pfeil 31.2 Die Skriptsprache Perl
Pfeil 31.2.1 Aufbau eines Skripts
Pfeil 31.2.2 Variablen
Pfeil 31.2.3 Kontrollstrukturen
Pfeil 31.2.4 Subroutinen
Pfeil 31.2.6 Arbeiten mit dem Dateisystem
Pfeil 31.3 Zusammenfassung
Pfeil 31.4 Aufgaben

Rheinwerk Computing - Zum Seitenanfang

31.2 Die Skriptsprache PerlZur nächsten Überschrift

Im Folgenden werden wir Ihnen einen Crashkurs zur Programmierung mit Perl geben. Warum aber ausgerechnet Perl? Perl hat als Programmiersprache seine Stärken vor allem in der Verarbeitung von Textdaten, beispielsweise mit regulären Ausdrücken. Entsprechend wird Perl sehr gern in der Webprogrammierung sowie im Bereich der Systemadministration eingesetzt – und zwar meist genau da, wo ein normales Shellskript an seine Grenzen stößt.

Für Perl existieren zahlreiche Erweiterungen, sogenannte Module. über die jeweils passenden Module können zum Beispiel Datenbanken

angesprochen oder CGI-Skripte für dynamische Webseiten erstellt werden.


Rheinwerk Computing - Zum Seitenanfang

31.2.1 Aufbau eines SkriptsZur nächsten ÜberschriftZur vorigen Überschrift

Wie jedes Skript (und wie auch bereits in der Kurzvorstellung der Sprache erwähnt wurde) startet ein Perl-Skript stets mit der Angabe des Interpreters in der Form:

Listing 31.128 Interpreter angeben

#!/usr/bin/perl

Oft wird der Interpreter mit -wT aufgerufen, was viele Warnmeldungen des Interpreters aktiviert und dringend zu empfehlen ist. Meist folgen dann ein paar Kommentare über das Programm selbst, wie es aufgerufen wird und was es tut. Kommentare beginnen in Perl wie bei vielen Skriptsprachen mit einer Raute (#).

Module einbinden

Nach ein paar einleitenden Kommentaren werden in der Regel die für das Skript benötigten Module eingebunden. Der entsprechende Befehl heißt

use:

Listing 31.129 Einbinden von zwei Modulen

use DBD::mysql;
use HTML::Mason;

Wenn man selbst Perl programmiert beziehungsweise ein fremdes Perl-Skript auf eigenen Systemen nutzen will, kann es vorkommen, dass man ein benötigtes Modul nicht installiert hat. Dann hilft CPAN, eine Online-Sammlung, die nahezu sämtliche Perl-Module umfasst.

Module vom CPAN installieren

Das Installieren neuer Module über CPAN gestaltet sich dank der komfortablen CPAN-Shell recht einfach. Es gengt ein Aufruf des cpan-Programms:

Listing 31.130 Über CPAN Module installieren

# cpan
[... bei dem ersten Aufruf wird die CPAN-Shell initialisiert bzw.
komplett installiert ...]
cpan> install HTML::Mason
[...]
cpan> exit

Nach diesem Aufruf ist das entsprechende Modul – zumindest sofern es während der Installation keinen Fehler gab – auf dem System vorhanden und kann sofort in Skripten benutzt werden.

Nach der Angabe der nötigen Module folgt der eigentliche Skriptcode. Ein erstes Beispielprogramm, das den Text »hello, world!« ausgibt, sieht wie folgt aus:

Listing 31.131 Hello, World in Perl

#!/usr/bin/perl
#
# helloworld.pl
#
# gibt "hello, world!" aus.

# strenge Syntaxregeln aktivieren
use strict;

print "hello, world!\n";

Um das Programm auszuführen, müssen Sie es nur über das Execute-Flag als ausführbar markieren und anschließend aufrufen:

Listing 31.132 Ein Perl-Skript ausführbar machen und starten

$ chmod +x helloworld.pl
$ ./helloworld.pl
hello world!
$

Rheinwerk Computing - Zum Seitenanfang

31.2.2 VariablenZur nächsten ÜberschriftZur vorigen Überschrift

Um nun ein Skript überhaupt mit etwas Dynamik ausstatten zu können, müssen Sie Perl-Variablen verstehen, die wir im Folgenden erläutern werden.

Variablentypen

Variablentypen werden in Perl durch ein Präfix identifiziert. Die wichtigsten Variablentypen sind:

  • $ – Skalare
    Skalare sind Variablen, die genau einen Wert aufnehmen. Skalare haben keinen expliziten Typ, können also sowohl Zahlen als auch Zeichenketten speichern.
  • @ – Arrays
    Arrays fassen mehrere Skalare zu einem Feld zusammen. Die einzelnen Einträge werden über eine Zahl indiziert.
  • % – Hashes
    Hashes sind assoziative Arrays. Einträge werden daher nicht über eine Zahl, sondern über eine Zeichenkette indiziert.

[»]Vor der Benutzung sollten Sie [Fn. ... beziehungsweise: müssen Sie bei Verwendung von use strict] Variablen über das Schlüsselwort my deklarieren. Anders als in ANSI-C können Variablen jedoch überall deklariert werden, wo Sie es für nötig halten. Gern gesehen wird jedoch – wie bei C üblich – eine Deklaration am Anfang eines Codeblocks.

Am konkreten Beispielskript sieht eine solche Deklaration wie folgt aus:

Listing 31.133 Variablen in Perl

#!/usr/bin/perl

use strict;

my $var1 = "Hallo"; # String
my $var2 = 5; # Zahl

my @array;
my %hash;

$array[1] = 2; # eine Zahl im Array speichern...
$array[2] = "foo"; # ...ein Text...

$hash{'passwort'} = "xxx"; # ...im Hash...

Das Beispiel zeigt auch, wie man auf den Inhalt von Arrays und Hashes zugreift: nämlich über den $-Operator. Dies ist sinnvoll, wenn man bedenkt, dass man beim Zugriff einen bestimmten Wert auslesen will, denn konkrete, skalare Werte werden grundsätzlich über $ angesprochen.

Typisierung

Des Weiteren können Sie sehen, dass es in Perl anders als in C keine strenge oder explizite Typdeklaration gibt. Es ist für Perl unwesentlich, ob Sie einen Text oder eine Zahl in einem Skalar speichern. Perl bestimmt den Typ einer Variablen dynamisch beim Ausführen des Skripts anhand des benutzten Kontexts:

Listing 31.134 Typisierung

#!/usr/bin/perl

use strict;

my $var1 = "Hallo"; # String
my $var2 = 5; # Zahl
my $var3 = "5"; # String? Zahl?

print $var2 + $var3 . "\n";
print $var1 + $var2 . "\n";
print $var1 + $var3 . "\n";
print $var1 . $var2 . "\n";
print $var1 . $var3 . "\n";

Die Ausführung des Skripts ergibt folgende Ausgabe:

Listing 31.135 Typisierung #2

$ ./typ.pl
10
5
5
Hallo5
Hallo5
$

Der Operator + addiert zwei Zahlen, während der Operator . zwei Strings miteinander verbindet. Im ersten Ausdruck werden die Variablen var2 und var3 als Zahlen interpretiert: 5 + 5 = 10. Das Ergebnis wird als String interpretiert, mit einem Zeilenumbruch versehen und per print ausgegeben.

In den nächsten beiden Ausdrücken wird versucht, einen String zu einer Zahl zu addieren. Offensichtlich wird der String dabei als »0« interpretiert, denn heraus kommt beide Male »5« als Ergebnis.

In den letzten beiden Ausdrücken werden schließlich wieder Zahlen als Strings interpretiert und per . mit var1 verknüpft.

Tabelle 31.3 Übersicht der arithmetischen Operatoren

Operator Beispiel Beschreibung

+

$x = $x + 1

Addition

-

$x = $x1

Subtraktion

}

$x = $y * $z

Multiplikation

/

$z = $x / $y

Division

%

$m = $x % $y

Modulo (Restwert bei Division)

++

$x++

Inkrement

--

$x--

Dekrement

&

$x = $y & $z

logisches UND

|

$x = $y | $z

logisches ODER

^

$x = $y ^ $z

logisches XOR

Die arithmetischen Operatoren sind, wie Sie sehen, im Wesentlichen analog zu denen in C.


Rheinwerk Computing - Zum Seitenanfang

31.2.3 KontrollstrukturenZur nächsten ÜberschriftZur vorigen Überschrift

Mit Variablen kann man nun viele schöne Dinge tun, beispielsweise indem man Anweisungen in Kontrollstrukturen füttert. Im Prinzip kennen Sie die Bedingungen if, for und while schon aus der Shell und von C – und auch bei Perl ändern sich die grundlegenden Prinzipien ihre Verwendung nicht.

Bei allen Kontrollstrukturen müssen Sie Bedingungen schreiben – beispielsweise unter Benutzung der bekannten arithmetischen Vergleichsoperatoren (siehe Abschnitt Vergleichsoperatoren) oder auch durch String-Vergleiche, die auf regulären Ausdrücken basieren und die wir in Abschnitt Perl_RegEx noch vorstellen werden.

if – bedingte Anweisungen

Wie bereits gesagt wurde, funktionieren bedingte Anweisungen mit if analog zu C, es gibt weitgehend dieselben Operatoren, und auch && und || funktionieren analog zu C. Die geschweiften Klammern sollten Sie aber nie vergessen, auch wenn Sie nur eine Anweisung nach if ausführen wollen.

Listing 31.136 if-Anweisung

if ( $a == 1 && $b != 5 )
{
...
}

Im Unterschied zu C gibt es keine case-Anweisung. Anstelle von case können Sie jedoch if ... elsif ... else nutzen:

Listing 31.137 if-elsif-else

if ( $a == 1 ) {
...
} elsif ( $a == 2 ) {
...
} elsif ( $a == 3 ) {
...
} else {
# alle anderen Werte von $a
...
}

So weit gibt es eigentlich nichts Neues.

for-Schleifen

Interessanter sind da schon die for-Schleifen. Hier kann man nämlich eine Syntax analog zu C und eine andere Syntax analog zur bash nutzen. Die aus C bekannte Variante schreibt sich wie folgt:

Listing 31.138 Die Anweisung for analog zu C

for(my $i = 1; $i <= 100; $i++) {
print "$i\n";
}

foreach

Man gibt einen Startwert, eine Bedingung und eine Anweisung an, die nach jedem Durchlauf ausgeführt wird. Aber durch das Schlüsselwort foreach ist auch eine Anwendung ähnlich zu for in der bash möglich, womit eine Liste von Werten – im Sinne eines Arrays oder Hashs – recht einfach durchlaufen werden kann:

Listing 31.139 Die Anweisung for analog zur bash

my @bar = ("mein Haus", "mein Auto", "mein Boot");

foreach $foo (@bar)

{
print "$foo !\n";
}

Die Syntax von foreach erklärt sich eigentlich beim Lesen des Beispiels von selbst: Man gibt eine Variable an, mit der im Schleifenkörper das jeweils aktuelle Element bezeichnet werden soll. Das zu durchlaufende Array folgt in Klammern.

Hashes durchlaufen

In diesem Beispiel haben Sie auch gesehen, wie man ein Array verkürzt definieren kann: als eine Liste von Werten. Im nächsten Beispiel werden Sie sehen, wie man ein Hash verkürzt definieren und es mit foreach durchlaufen kann.

Listing 31.140 foreach mit Hash

#!/usr/bin/perl

use strict;

my %hash = (1 => "3", foo => "bar");
my $x;

foreach $x (%hash)
{
print $x . "\n";
}

Wenn man ein Hash verkürzt definiert, ordnet man mittels des Operators => einem Schlüssel einen Wert zu. Dass man über foreach dann sowohl Schlüssel als auch Werte durchlaufen kann, zeigt der Output des Skripts:

Listing 31.141 foreach mit Hash: Output

$ ./foreach.pl
1
3
foo
bar
$

while-Schleifen

Wieder analog zu C funktionieren einfache while-Schleifen. Man definiert eine Bedingung und einen Schleifenkörper, der so lange ausgeführt wird, wie die Bedingung wahr ist. Ist die Bedingung nie wahr, wird der Schleifenkörper auch nie ausgeführt.

Listing 31.142 while-Schleife

while ($a != $b)
{
# natürlich sollte der Schleifenkörper jetzt irgendwann etwas an
# $a oder $b ändern
...
}

Hashes eleganter durchlaufen

Aber while-Schleifen bieten auch eine etwas elegantere Art, Hashes zu durchlaufen:

Listing 31.143 while-Schleife mit Hashes

while (($s,$w) = each(%hash))
{
print "Schlüssel: " . $s . " Wert: " . $w . "\n";
...
}

Bei dieser Methode erhält man im Gegensatz zu foreach unterschiedliche Variablen für Schlüssel und Wert. Die Schleife bricht ab, wenn es keine Werte mehr zu durchlaufen gibt.

do-while-Schleifen

Die ebenfalls aus C bekannte do-while-Schleife verhält sich analog zu while – mit dem Unterschied, dass die Bedingung erst nach dem Schleifenkörper geprüft wird. Das hat zur Folge, dass diese Schleife mindestens einmal ausgeführt wird, auch wenn die Bedingung immer falsch ist.

Listing 31.144 do-while-Schleife

do
{
# wird mindestens einmal ausgeführt
...
} while ( 1 != 2 )

[»]Da eventuell in der Bedingung zugewiesene Variablen erst nach dem ersten Durchlauf zugewiesen werden, eignet sich do-while nicht zum Durchlaufen von Hashes oder Arrays. Folgendes funktioniert demzufolge nicht wie gewünscht: [Fn. Beim ersten Durchlauf ist die Variable $s noch leer beziehungsweise mit einem alten Wert gefüllt.]

Listing 31.145 do-while-Schleife falsch eingesetzt

do
{
print $s;
...
} while ( ($s,$w) = each(%hash) )

TIMTOWTDI

Spätestens an dieser Stelle müssen wir Ihnen auch eines der zentralen Prinzipien von Perl erläutern: TIMTOWTDI [Fn. Sprich: »Tim Toady«.] – »There is more than one way to do it«, Es gibt mehr als einen Weg, es zu tun. [Fn. Nicht nur im Kamasutra, sondern auch in Perl ...]

Perl ist bekannt dafür, dass man identische Sachverhalte unterschiedlich formulieren kann. Dadurch wird Perl auch oft unterstellt, ziemlich unlesbar zu sein, frei nach dem Motto: »Write once, never understand again«. [Fn. In Verballhornung des Java-Mottos »Write once, run anywhere«.] Fakt ist aber, dass man zwar in Perl ziemlich furchtbaren, aber auch sehr schönen Code schreiben kann – die Freiheit liegt beim Programmierer.

unless und until

unless und until

Ein Beispiel für diese Freiheit des Programmierers liefert die Negation. So gibt es für if und while jeweils eine Variante, die exakt die Negation der Bedingung ausdrückt. So führt unless den zugehörigen Anweisungsblock nur aus, wenn die angegebene Bedingung falsch ist:

Listing 31.146 unless

# folgende Anweisungen sind äquivalent
if (! $a == $b )
{
Anweisung1;
...
}

unless ( $a == $b )

{
Anweisung1;
...
}

Analog führt until den Schleifenkörper so lange aus, wie die angegebene Bedingung falsch ist. Somit ist until gewissermaßen die Negation von while:

Listing 31.147 until

# folgende Anweisungen sind äquivalent
while (! $a == $b )
{
Anweisung1;
}

until ( $a == $b )

{
Anweisung1;
}

Natürlich gibt es auch eine entsprechende do-until-Variante, die – je nach Lust und Laune des Programmierers – do-while ersetzen kann.

Nachstellung

Eine weitere Besonderheit ist, dass Sie alle Kontrollstrukturen – if, for, while, until und unless – bei einzelnen Anweisungen auch nachstellen können. Die Bedeutung verändert sich dadurch nicht:

Listing 31.148 Die Nachstellung

# Es ist egal, ob Sie es so:
if ( $x == $y ) print "foo\n";

# ...oder so schreiben:
print "foo\n" if ( $x == $y );

Im Besonderen können bei Nachstellungen die geschweiften Klammern weggelassen werden. Jedoch sollte man im Umgang mit Nachstellungen auch vorsichtig sein:

Listing 31.149 Achtung, eklig!

#!/usr/bin/perl

use strict;

print "1\n" while ( 4 == 5 );

do { print "2\n"; } while ( 4 == 5 );

Hätten Sie auf den ersten Blick gesehen, dass das Skript beide Schleifen unterschiedlich behandelt und den folgenden Output produziert?

Listing 31.150 Achtung, eklig #2

$ ./eklig.pl
2

Zwar ist in beiden Listings 4 nicht gleich 5, jedoch wird eine do-while-Schleife immer mindestens einmal durchlaufen, während eine while-Schleife nur dann durchlaufen wird, wenn die Bedingung mindestens einmal wahr ist – und daran ändert auch eine Nachstellung nichts. Aufgrund der syntaktischen Ähnlichkeiten sollte man daher nachgestellte while-Schleifen nur mit äußerster Vorsicht einsetzen.

Fazit

Alle in diesem Abschnitt geschilderten Möglichkeiten erlauben es, den Code der natürlichen Sprache anzunähern und damit lesbarer zu gestalten. Durch die Verwendung von until und unless können Sie »unnötige« Negationen verhindern und durch die Nachstellung unter Umständen den Lesefluss fördern. Perl lässt Ihnen also viele Freiheiten, mit denen Sie sehr schönen Code schreiben, aber auch Schindluder treiben können.


Rheinwerk Computing - Zum Seitenanfang

31.2.4 SubroutinenZur nächsten ÜberschriftZur vorigen Überschrift

Subroutinen lassen sich in Perl prinzipiell an jeder Stelle des Skripts definieren, jedoch findet man sie in der Regel am Anfang oder am Ende des Codes. Eingeleitet werden sie mit dem Schlüsselwort sub:

Listing 31.151 Subroutinen definieren

sub meineFunktion {
# Code...
}

Aufrufen können Sie eine Subroutine genau wie normale Befehle:

Listing 31.152 Subroutinen benutzen

#!/usr/bin/perl

use strict;

# Subroutinen definieren
sub Ausgabe {
print "Hallo, Welt!\n";
}

# Der "eigentliche" Code, das "Hauptprogramm"
Ausgabe();
Ausgabe();

Dieses Beispiel produziert zwei Zeilen »Hallo, Welt!«-Text als Ausgabe, da die entsprechende Subroutine im Hauptprogramm zweimal hintereinander aufgerufen wurde.

Argumente übergeben

Subroutinen lassen sich selbstverständlich auch mit Argumenten füttern. Dazu deklariert man am Anfang der Subroutine Variablen, denen man mittels des Schlüsselworts shift einen Wert zuweist. Per shift greift man auf die Argumente des Aufrufs zu, eine weitere Deklaration ist nicht erforderlich:

Listing 31.153 Argumente übergeben

#!/usr/bin/perl

use strict;

sub Funktion {
my $i = shift;
my $text = shift;
print $text . " " . $i . "\n";
}

Funktion(1, "hallo");

Dieses kleine Beispiel gibt den Text »hallo 1« aus. Das ist nicht sehr sinnvoll, genügt aber zur Demonstration von shift fürs Erste.

Rückgabewerte benutzen

Normalerweise endet eine Subroutine, wenn ihr Ende erreicht ist – aber selbstverständlich kann sie auch Werte an den Aufrufer zurückgeben beziehungsweise schon an anderer Stelle beendet werden. Anders als in C muss dies jedoch nicht explizit deklariert werden, da dem Schlüsselwort return einfach ein beliebiger Wert übergeben werden kann – oder eben auch nicht.

Listing 31.154 Rückgabewerte definieren

#!/usr/bin/perl

use strict;

sub Funktion {
my $i = shift;

if( $i == 1 ) {
return "Alles Ok\n";
} else {
return "Nix ist Ok\n";
}
}

print Funktion(1);
print Funktion(0);

31.2.5 Reguläre AusdrückeZur nächsten ÜberschriftZur vorigen Überschrift

Zu regulären Ausdrücken gibt es ein eigenes Kapitel. Sie sollten also zum Beispiel wissen, worauf ein Ausdruck wie ^h[abc]ll.$ passt (man sagt auch: matcht) und worauf nicht. [Fn. Wenn nicht, können Sie das entsprechende Thema in Kapitel kap_regex nachlesen.] Daher wollen wir in diesem Abschnitt nur kurz auf die Besonderheiten von regulären Ausdrücken in Perl eingehen.

Unter Perl ist der Operator =\~ speziell für die Arbeit mit regulären Ausdrücken gedacht. Ob Sie nun prüfen wollen, ob ein Text auf einen solchen Ausdruck passt, oder ob Sie eine Ersetzung auf Basis eines regulären Ausdrucks vornehmen wollen, =\~ ist der Operator Ihrer Wahl.

Suchen

Wenn Sie beispielsweise überprüfen wollen, ob ein Text einem bestimmten Muster entspricht, setzen Sie ein m (match) vor den regulären Ausdruck. Die Anwendung ist so einfach wie im Beispiel zu sehen:

Listing 31.155 Passt ein Text?

my $text = "Hallo";

if( $text =~ m/^H/ )
{
print $text . " fängt mit H an!\n";
}

So können Sie ohne Weiteres prüfen, ob eine Eingabe einem bestimmten Muster entspricht. Die regulären Ausdrücke selbst funktionieren im Wesentlichen wie die von sed, mit dem Unterschied, dass Sie sich nicht über das Escapen von Sonderzeichen auf der Shell Gedanken machen müssen.

Ersetzen

Wenn Sie über einen regulären Ausdruck nicht nur Muster prüfen, sondern auch Veränderungen am Text vornehmen wollen, hilft Ihnen das Präfix s weiter. Wie das funktioniert, zeigt folgendes kleines Beispiel:

Listing 31.156 Mit regulären Ausdrücken Text ersetzen

#!/usr/bin/perl
use strict;

my $text = "vorher";

print $text . "\n";
$text =~ s/vor/nach/;

print $text . "\n";

Dieses kleine Skript ersetzt im String »vorher« die Silbe »vor« durch »nach«. Natürlich sind auch weit kompliziertere Ersetzungen möglich, in diesem Kapitel werden wir jedoch nur einige wenige, aber wichtige Beispiele bringen.

Globale Ersetzung

Normalerweise wird bei einer Ersetzung nur das erste gefundene Vorkommen ersetzt. Möchte man alle Vorkommen ersetzen, so muss man dem Suchausdruck ein g (global) folgen lassen:

Listing 31.157 global.pl

#!/usr/bin/perl
use strict;

my $text = "texttexttext";

print $text . "\n";
$text =~ s/text/blah/;
print $text . "\n";
$text =~ s/text/blah/g;

print $text . "\n";

Die Ausgabe verdeutlicht noch einmal den Effekt, dass ohne das g nur das erste Vorkommen ersetzt wird:

Listing 31.158 Globale Ersetzung

$ ./global.pl
texttexttext
blahtexttext
blahblahblah

Darüber hinaus kann man sich über die Benutzung von einfachen Klammern, ( und ), Textteile »merken«. Diese gemerkten Textteile kann man im Ersetzungsteil über die Variablen $1, $2 usw. ansprechen:

Listing 31.159 klammer.pl

#!/usr/bin/perl

use strict;

my $text = "passwort : user";

print $text . "\n";
$text =~ s/^(.*) : (.*)$/Der Benutzer $2 hat das Passwort $1!/g;

print $text . "\n";

Dieses Skript liefert folgende Ausgabe:

Listing 31.160 Zeichenketten vertauschen

$ ./klammer.pl
passwort : user
Der Benutzer user hat das Passwort passwort
$

Dieser Mechanismus ist also vor allem dann geeignet, wenn Zeichenketten in Strings »vertauscht« werden sollen.

Einzelne Zeichen ersetzen

Ähnlich dem Kommando tr in der Shell funktioniert der Modifikator tr für reguläre Ausdrücke. Mit ihm können einzelne Zeichen in einem kompletten String ersetzt werden:

Listing 31.161 tr.pl

#!/usr/bin/perl

use strict;

my $text = "abcdefg";

print $text . "\n";
$text =~ tr/aceg/1234/;
print $text . "\n";

In diesem Beispiel werden die Zeichen a,c,e und g durch die Ziffern 1 bis 4 ersetzt:

Listing 31.162 Zeichen ersetzen

$ ./tr.pl
abcdefg
1b2d3f4

So viel sei zur Benutzung regulärer Ausdrücke unter Perl gesagt; mehr grundsätzliche Informationen zu regulären Ausdrücken an sich finden Sie in Kapitel 8.


Rheinwerk Computing - Zum Seitenanfang

31.2.6 Arbeiten mit dem DateisystemZur nächsten ÜberschriftZur vorigen Überschrift

Die Arbeit mit Dateien gestaltet sich in Perl ähnlich wie bei C. So werden Dateien beispielsweise über sogenannte Filehandles identifiziert, die im Prinzip nichts anderes als Deskriptoren sind. Auch in Perl werden Dateien erst geöffnet, bevor sie gelesen beziehungsweise geschrieben werden können, und natürlich müssen sie auch hier wieder geschlossen werden.

Dateien öffnen

open()

Dateien werden über den Aufruf open() geöffnet. Er nimmt zwei Parameter entgegen: den zu benutzenden Filehandle (den Deskriptor) sowie den zu öffnenden Dateinamen. Mithilfe der Zeichen <, > und |, die man dem Dateinamen voranstellt, kann man die Modi steuern, mit denen die Datei geöffnet werden soll.

Die einzelnen Modi heißen wie folgt:

  • <Datei
    Datei zum Lesen öffnen
  • >Datei
    Datei zum Schreiben öffnen
  • >>Datei
    Datei zum Schreiben öffnen. Wenn die Datei bereits existiert, werden die Daten an die Datei angehängt.
  • |Datei
    Hier ist Datei ein ausführbares Programm. Zu diesem Programm wird eine Pipe geöffnet, in die man anschließend schreiben kann.
  • Datei|
    In diesem Fall wird auch eine Pipe geöffnet, allerdings kann man jetzt aus der Pipe lesen.

Möchte man also eine Datei datei.txt zum Lesen öffnen, so kann man folgenden Code benutzen:

Listing 31.163 open

my $fh;

open($fh, «datei.txt");

Dabei wird die Variable $fh als Filehandle initialisiert. Später kann über diese Variable auf den Inhalt der Datei lesend oder – bei

entsprechenden open()-Modi – auch schreibend zugegriffen werden.

Lesen und schreiben

Das Lesen erfolgt normalerweise über eine Schleife. Gelesen wird die Datei dann zeilenweise, und in jedem Schleifendurchlauf kann eine Zeile bearbeitet werden. Um eine Zeile im Schleifenkopf auszulesen, fasst man den Filehandle in zwei spitze Klammern:

Listing 31.164 Lesen

# Die Datei $fh zeilenweise auslesen
while (defined (my $line = <$fh>)) {
# In $line finden Sie die aktuell gelesene Zeile
...
}

Ist die Datei fertig gelesen, bricht die Schleife automatisch ab, da keine neue Zeile mehr definiert ist. Das Schreiben erfolgt ganz ähnlich wie die Ausgabe auf der Kommandozeile, nur wird hier der Filehandle vor dem zu schreibenden Text angegeben.

Listing 31.165 Schreiben

# Den Text "Text" in die Datei schreiben
print $fh "Text";

Dateien schließen

Nach dem Bearbeiten muss der Filehandle schließlich noch korrekt geschlossen werden:

Listing 31.166 Datei schließen

close($fh);

Im folgenden Listing sehen Sie ein kleines Beispielprogramm, das eine Datei, deren Name auf der Kommandozeile übergeben wird, [Fn. Auf der Kommandozeile übergebene Parameter finden Sie im Array @ARGV.] einliest und mit Zeilennummern versehen ausgibt. Sehen wir uns den Code des Programms an, indem wir es durch sich selbst anzeigen lassen:

Listing 31.167 ausgabe.pl

$ ./ausgabe.pl ausgabe.pl
1: #!/usr/bin/perl
2:
3: use strict;
4:
5: my $fh;
6: my $num = 1;
7:
8: # den ersten übergebenen Parameter finden wir in $ARGV[0]
9: open($fh, «$ARGV[0]");
10:
11: while (defined (my $line = <$fh>)) {
12: print "$num: $line";
13: $num++;
14: }
15:
16: close($fh);
$

Dies soll uns erst einmal als kurze und knackige Einführung in Perl genügen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Linux Handbuch






 Linux Handbuch


Zum Katalog: Linux Server






 Linux Server


Zum Katalog: Raspberry Pi






 Raspberry Pi


Zum Katalog: Ubuntu 14.04 LTS






 Ubuntu 14.04 LTS


Zum Katalog: Roboter bauen mit Arduino






 Roboter bauen
 mit Arduino


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de