PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : kann mir jemand ein 3-Zeilen-Perlskript schreiben?


Binaermensch
2004-10-31, 21:24:36
moin!

Ich bin gerade dabei, mir in PHP einen Apache-Log-Analyzer zu schreiben. Leider hab ich jedoch gemerkt, dass PHP (im Gegensatz zu Perl) wegen SAFE_MODE keinen Zugriff auf die Datei hat.
Brauchen würde ich also ein Perlskript, das nichts anderes macht als den Inhalt von Datei durchzuschleifen. Dieses könnte ich dann aus PHP aufrufen, und käme damit trotz SAFE_MODE an die Logfile ran.


Wär toll wenn mir da jemand helfen könnte.. :)

Aqualon
2004-10-31, 21:44:46
open(READ_HANDLE, "FileName/Location");
open(WRITE_HANDLE,">>FileName/Location");
@raw_data=<READ_HANDLE>;
foreach $content (@raw_data) {
print WRITE_HANDLE $content;
}
close(READ_HANDLE);
close(WRITE_HANDLE);


Bisschen mehr als drei Zeilen, aber es sollte machen, was du willst.

Aqua

Binaermensch
2004-10-31, 22:35:36
Danke dass du dir die Mühe gegeben hast! :)
Irgendwas scheint da aber noch nicht zu passen..

"Serverfehler!

Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

Fehlermeldung:
Premature end of script headers: kopieren.pl"

Aqualon
2004-10-31, 23:10:06
Mal ein Beispiel:


open(READ_HANDLE, "/var/log/apache2/access_log");
open(WRITE_HANDLE,">/tmp/access_log");
@raw_data=<READ_HANDLE>;
foreach $content (@raw_data) {
print WRITE_HANDLE $content;
}
close(READ_HANDLE);
close(WRITE_HANDLE);


Das Skript öffnet die Datei access_log in /var/log/apache2/ und schreibt sie in die Datei access_log im /tmp/ Ordner. Du musst die Pfade entsprechend deiner Konfiguration anpassen und als Zielverzeichnis einen Ordner angeben, aus dem PHP auch lesen darf.

Noch eine Anmerkung zu open(WRITE_HANDLE,">/tmp/access_log");

Da ist es sinnvoller nur ein > zu verwenden und die Datei neu zu erstellen. Bei >> würde er denselben Inhalt ja immer wieder dranhängen.

Aqua

Binaermensch
2004-10-31, 23:37:29
Verzeichnispfade hab ich natürlich angepasst..

Mein Skript sieht jetzt folgendermaßen aus:
open(READ_HANDLE, "/home/www/ecn59/log/access_log");
open(WRITE_HANDLE,">/home/www/ecn59/files/access_log");
@raw_data=<READ_HANDLE>;
foreach $content (@raw_data) {
print WRITE_HANDLE $content;
}
close(READ_HANDLE);
close(WRITE_HANDLE);

Fehlermeldung (http://ecn59.e003-r1041.ec-i.net/cgi-bin/kopieren.pl) ist dieselbe.

Aqualon
2004-11-01, 04:18:57
Da bin ich gerade leider auch überfragt. Auf meinem lokalem System funktioniert das einwandfrei.

Aqua

Kant
2004-11-01, 05:17:31
Danke dass du dir die Mühe gegeben hast! :)
Irgendwas scheint da aber noch nicht zu passen..

"Serverfehler!

Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

Fehlermeldung:
Premature end of script headers: kopieren.pl"
a) Es MUSS unbedingt im Script ein Content-type gesetzt sein, also sowas:

print "Content-type: text/html\n\n";
print "wird kopiert...\n";

b) In der Startzeile wo normal etwas wie #!/usr/bin/perl steht, ein "--" dahintersetzen, also in diesem Stil:

#!/usr/bin/perl --

Häufig ist es auf Unix-System so, das das Script beim upload falsche Zeichen am Zeilenende "bekommt", mit dem "--" wird alles danach ignoriert, dann startet auf jeden Fall schon mal die Perl-Binary.
c) Ein

use CGI::Carp "fatalsToBrowser";

in die 2. Zeile setzen. Damit werden Fatale Fehler auch im Browser angezeigt. (Wenn damit auch nicht mehr angezeigt wird, liegt es fast immer an b), also einem Fehler schon in der ersten Zeile, wo der Interpreter geladen wird)

d) Ein Blick ins Error-Log ist auch oft nützlich.

Also final so etwas ....

#!/usr/bin/perl --
use CGI::Carp "fatalsToBrowser";

$EINGABE="/ich/liege/hier.log";
$AUSGABE="/ich/soll/dahin.log";

print "Content-type: text/html\n\n";
print "Kopiere $EINGABE nach $AUSGABE\n";
if (!open(EIN,"<".$EINGABE)) {
print "Datei $EINGABE kann nicht geöffnet werden.\n";exit(0);
}
if (!open(AUS,">".$AUSGABE)) {
print "Datei $AUSGABE kann nicht angelegt werden.\n";exit(0);
}
while(!eof(EIN)) {
$Zeile=<EIN>;print AUS $Zeile;
}
close(EIN);
close(AUS);
print "Datei ist kopiert.\n";


Edit : Ist im Prinzip wie die version von Aqualon, nur das die Datei nicht komplett in den Speicher gelesen und dann geschrieben wird, sondern jeweils zeilenweise gelesen/geschrieben wird. Kann bei großen Logs und kleinen Rams sonst Probleme geben ;)

Binaermensch
2004-11-01, 15:28:48
#!/usr/bin/perl --
use CGI::Carp "fatalsToBrowser";

$EINGABE="/home/www/ecn59/log/access_log";
$AUSGABE="/home/www/ecn59/files/access_log";

print "Content-type: text/html\n\n";
print "Kopiere $EINGABE nach $AUSGABE\n";
if (!open(EIN,"<".$EINGABE)) {
print "Datei $EINGABE kann nicht geöffnet werden.\n";exit(0);
}
if (!open(AUS,">".$AUSGABE)) {
print "Datei $AUSGABE kann nicht angelegt werden.\n";exit(0);
}
while(!eof(EIN)) {
$Zeile=<EIN>;print AUS $Zeile;
}
close(EIN);
close(AUS);
print "Datei ist kopiert.\n"; Irgendwas scheints da zu haben..
Der Perl-Pfad stimmt aber. Andere Perlskripte funzen problemlos..Serverfehler!

Die Anfrage kann nicht beantwortet werden, da im Server ein interner Fehler aufgetreten ist.

Fehlermeldung:
Premature end of script headers: kopieren.pl

Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.
Error 500
ecn59.e003-r1041.ec-i.net
Mon Nov 1 15:29:11 2004
Apache/2.0.48 (Linux/SuSE)

Aqualon
2004-11-01, 17:55:57
Edit : Ist im Prinzip wie die version von Aqualon, nur das die Datei nicht komplett in den Speicher gelesen und dann geschrieben wird, sondern jeweils zeilenweise gelesen/geschrieben wird. Kann bei großen Logs und kleinen Rams sonst Probleme geben ;)
Ok, Punkt für dich ;) Wobei ich ehrlich gesagt nicht unbedingt Logfiles mit ein paar 100MB Größe in PHP auswerten wollen würde.

@Binärmensch: Kommentiere einmal die Zeilen für die Ein- und Ausgabe aus. Wenn es dann läuft, hat Perl wohl nicht die Berechtigung auf einen oder beide der Ordner zuzugreifen.

Aqua

Binaermensch
2004-11-01, 18:39:50
Hab das mit dem Auskommentieren mal probiert..
Ergebnis: noch nichtmal folgender Code funktioniert anständig :|
(AWstats funzt aber aus irgendeinem Grund ohne probleme)

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print "Datei ist kopiert.\n";


Ich werde mich mal mit meinem Hoster in Verbindung setzen.

Kant
2004-11-01, 19:20:28
Hast du dem Script auch Ausführechte gegeben?

Ansonsten setze sowohl Dateiendung (.pl,.cgi), als auch die Dateirechte auf Werte von funktionierenden Perl-Scripten.