PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Perl] mehrere Probleme (Dateitestoperatoren, Shell-Skript Portierung)



ClausVB
19-04-2006, 18:13
Hallo!

Ich möchte folgendes Shellskript

GKZ_DBPATH="$GKZ_HOMEDIR/webspace/databases"
GKZ_BACKUPPATH="$GKZ_HOMEDIR/backup"

# FOR-Schleife um alle Pfade anzulegen (plus Logfile)
for thisdir in $GKZ_BACKUPPATH $GKZ_DBPATH; do
if [ ! -d "$thisdir" ] ;then
mkdir -p $thisdir
echo Versuche Verzeichnis $thisdir anzulegen ... >> $GKZ_HOMEDIR/logfile_$GKZ_DOMAIN.txt
if [ ! -d "$thisdir" ] ;then
echo =\> FEHLGESCHLAGEN >> $GKZ_HOMEDIR/logfile_$GKZ_DOMAIN.txt
exit 1
else
echo =\> erfolgreich >> $GKZ_HOMEDIR/logfile_$GKZ_DOMAIN.txt
fi
fi
done
nach Perl portieren.

Dazu habe ich mir -[x] - Dateitestoperatoren für Dateien/Verzeichnisse (http://de.selfhtml.org/perl/funktionen/dateiverwaltung.htm#dateitest) durchgelesen.

Nach ein bißchen probieren habe ich es mit

my $boolean = (-e $perl_datei) ? 1 : 0;
hinbekommen, zu überprüfen, ob ein Verzeichnis existiert oder nicht.

Der Perl-Befehl "mkdir" scheint aber im Gegensatz zum Linux-Befehl den Nachteil zu haben, dass es die Option "-p" nicht gibt.

Meine Frage: Kann ich (z.B. mit "system()") den Linux-Befehl anwenden und mir irgendwie zurückgeben lassen, ob die Operation geklappt hat?

Beispiel: exec "mkdir -p $thisdir";

Alternativ könnte ich nach dem "system()" auch noch einmal überprüfen, ob das Verzeichnis angelegt wurde.

Danke und Gruß
Claus

ClausVB
20-04-2006, 07:46
Nachtrag: Ich bin schon ein Stück weiter, aber etwas funktioniert nicht so wie ich es erwarten würde.

Der folgende Aufruf auf Shell-Ebene funktioniert einwandfrei:

perl -e 'print system("mkdir /opt/lampp/htdocs/einfuehrung_perl/docs2")';
Ich bekomme die Fehlermeldung: "mkdir: cannot create directory `/opt/lampp/htdocs/einfuehrung_perl/docs2': File exists"

Packe ich das in eine Datei, bekomme ich immer nur "0" zurück. Egal ob das Verzeichnis existiert oder nicht. Hier der Code:

my $mkdir_docs = system("mkdir -p /opt/lampp/htdocs/einfuehrung_perl/docs2");
print "MKDIR: $mkdir_docs\n";

Dabei ist es egal, ob ich das wie oben oder so

print system("mkdir -p /opt/lampp/htdocs/einfuehrung_perl/docs2");

schreibe.

Was mache ich falsch?

Ich bin es von PHP gewohnt, das 1 gleich TRUE und 0 gleich FALSE ist. Ist das unter Perl auch so?

Danke und Gruß
Claus

michael.sprick
20-04-2006, 08:48
Hi,

system() gibt Dir nur den Rückgabewert des Befehls zurück, den Du ausgeführt hast. Wenn dieser 0 ist, dann war der Befehl erfolgreich. Im Prinzip ist das return value das Selbe wie $? auf der Shell.

Das system() immer eine 0 zurückgibt, liegt an der Option '-p'


man mkdir
(Thus, if a directory /a exists, then `mkdir /a' is an error, but `mkdir -p /a' is not.)

Wenn Du die Option weglässt, wird auf STDERR eine entsprechende Fehlermeldung ausgegeben.

Wenn Du die Ausgabe des Befehls abfangen willst, musst du entweder

#Backticks verwenden
my $var = `ls -la`;
oder

# qx benutzen
my $var = qx(ls -la);

siehe dazu auch perldoc -f system und perldoc perlop

ClausVB
21-04-2006, 09:06
Das system() immer eine 0 zurückgibt, liegt an der Option '-p'
Das war der Knackpunkt, danke!

Hier noch einmal für Foren-User, die ein ähnliches Problem haben ...

Mein Skript oben funktioniert einwandfrei, mein Denkfehler war einfach die Option "-p".

man mkdir:

-p, --parents
no error if existing, make parent directories as needed (wie Michael schon richtig gesagt hat).

Lässt man die Option weg:

my $mkdir_befehl = "mkdir /opt/lampp/htdocs/einfuehrung_perl/test_mkdir/unter";
my $mkdir_docs = system($mkdir_befehl);
print "MKDIR: $mkdir_docs\n";
erscheint völlig richtig

mkdir: cannot create directory `/opt/lampp/htdocs/einfuehrung_perl/test_mkdir/unter': File exists

Wenn ein Berechtigungsproblem vorliegt, wird der Fehler (auch mit "-p") ordentlich zurückgegeben:

mkdir: kann Verzeichnis »/opt/lampp/htdocs/einfuehrung_perl/test_mkdir/unter« nicht anlegen: Keine Berechtigung

Das heißt, bei einer Rückgabe von 0 kann ich davon ausgehen, dass das Verzeichnis angelegt wurde und ansonsten existiert es ja bereits. Wenn ein Berechtigungsproblem oder ein anderer Fehler auftaucht, schreibe ich diesen in ein Logfile.

=> Problem gelöst

Tausend Dank, Michael!
Claus

michael.sprick
21-04-2006, 09:17
Lässt man die Option weg:

my $mkdir_befehl = "mkdir /opt/lampp/htdocs/einfuehrung_perl/test_mkdir/unter";
my $mkdir_docs = system($mkdir_befehl);
print "MKDIR: $mkdir_docs\n";
erscheint völlig richtig

mkdir: cannot create directory `/opt/lampp/htdocs/einfuehrung_perl/test_mkdir/unter': File exists
Claus

Wobei die Fehlermeldung nicht durch das 'print' ausgegeben wird... Diese wird vom mkdir-Befehl direkt an STDERR geschickt. Die Print-Anweisung gibt einzig und allein den Rückgabewert (also 0 bzw. Fehlernummer) aus.

Um das zu verhindern, kannst Du noch das Filehanlde STDERR im Perlskript schließen und anschließend wieder öffnen, um zum Beispiel derlei Meldungen in ein Logfile zu schreiben.



close(STDERR);
open(STDERR,">>logfile.txt");
select STDERR; $|++; select STDOUT;
...
close(STDERR);