Arbeitsverzeichnis unter Wampp/Xampp 'manipuliert'?

Alles, was Perl betrifft, kann hier besprochen werden.

Arbeitsverzeichnis unter Wampp/Xampp 'manipuliert'?

Postby cv » 11. September 2003 10:39

Hallo,

ich versuche, das Wampp_2.2-Paket (hiess da noch so) unter w2k als Entwicklungsumgebung zu nutzen. Meine Perl-Skripte verwenden lokale 'Bibliotheken', d.h. *.pl-Dateien im cgi-Verzeichnis mit gemeinsam genutzten Funktionen, die mit
Code: Select all
require "./mybibl.pl";

eingebunden werden. Das funktioniert auf dem Produktionsserver so + das lief auch unter der alten handgestrickten E-Umgebung (Apache 1.3, Perl 5.6 etc.). In der Wampp-Umgebung aber nicht: da gibt es nur die Fehlermeldung, "./mybibl.pl" sei im @INC-Pfad nicht zu finden.

Das ist auch richtig: Wenn ich mir die Include-Verzeichnisse ausgeben lasse, ist "." zwar wie gehabt dabei; ermittle ich dagegen das aktuelle Arbeitsverzeichnis mit cwd() bzw. getcwd(), bekomme ich keineswegs das Directory des aufgerufenen Scripts, sondern
Code: Select all
[Lw.:] / wampp2


(Tatsaechlich liegt das Skript uebrigens unterhalb von wampp2/htdocs - ebenfalls um den Online-Server zu 'simulieren' -, und das ist auch so in der httpd.conf eingetragen.)

Wie kommt dieses merkwuerdige "Mapping" von "." zu Stande? Ich habe einen ("undokumentierten"?) Eintrag in der httpd.conf in Verdacht, finde dort aber nichts Einschlaegiges.

Hat jemand eine Idee dazu?

Dank vorab + Gruss
claus-volker
cv
 

Nachtrag

Postby cv » 16. September 2003 00:01

Hallo nochmal,

da das Board einige Aufrufe dieser Frage verzeichnet, interessiert's ja vielleicht doch den Einen oder Anderen. Ich habe zwar zwischenzeitlich noch keine perfekte Lösung gefunden, aber ein paar Details nachzutragen - die mir zudem auf Spezifika der Wampp2-Installation hin zu deuten scheinen.

Wenn Perl das einzubindende lokale Modul (und nichts anderes ist etwas mit require "./mybibl.pl" Angesprochenes) in @INC nicht findet, versucht man natürlich, dem @INC-Array ein bisschen auf die Spruenge zu helfen:
Code: Select all
use Cwd;
my $actpath = cwd(); # bzw: getcwd();
push @INC, $actpath;

o.ä. klappt aber nicht, weil cwd() das "Wampp-Root" zurückliefert. (Warum, weiss ich immer noch nicht - so wenig wie, warum eine Ausgabe aller ansprech*baren* 'Module' sehr wohl den Inhalt von "." liefert - incl. der "nicht gefundenen" Datei :-( Man kann das mit etwas wie:
Code: Select all
sub pms{
  if((/\.pm/i) || (/\.pl/i)) {
    my $current_dir = cwd();
    print "$current_dir $_\n";
  }
}
foreach my $dir (@INC){
  find(\&pms, $dir);
}

ausprobieren.

Zurück zur @INC-Manipulation. Verlaesslicher als cwd ist
Code: Select all
use FindBin;
use lib $FindBin::Bin;

Das 'findet' den korrekten Pfad und trägt ihn in @INC ein, aber bloss für genau einen (den ersten) Script-Aufruf. Danach ist er wieder 'weg'. Das liegt offenbar an mod_perl. Bei S.Bekman finde ich u.d.T. "Coding with mod_perl in Mind":
Under mod_perl, @INC can be modified only during server startup. After each request, mod_perl resets @INC's value to the one it had before the request.

Dauerhaft veraendern könne man @INC nur ueber die (Apache-)httpd.conf:
Code: Select all
PerlSetEnv PERL5LIB /pfad/zu/perl:/pfad/zu/mybibl.pl

oder die [Lw:] / wampp2/apache/conf/startup.pl-Datei:
Code: Select all
use lib qw(/pfad/zu/perl /pfad/zu/mybibl.pl);
1;

[Quelle: S.B., "Practical mod_perl" http://www.webreference.com/programming/perl/mod_perl/chap6/3/.html
oder http://www.oreilly.com/catalog/pmodperl/chapter/ch06.pdf.]

Das kann man fuer seine Entwicklungsumgebung sicherlich gut machen; wenn man aber an die httpd.conf des Onlineservers nicht dran kommt oder die Scripte portierbar halten will, ist das keine allzu praktikable Lösung.

Ich behelfe mir im Moment mit einem 'Workaround':
Code: Select all
$ENV{'SCRIPT_FILENAME'} =~ /^([\w\.\:\-\/]*)\//gi;
my $actpath = $1;
require $actpath . '/' . "mybibl.pl";

scheint zu funktionieren - unter Windows + solange 'SCRIPT_FILENAME' in der Umgebung gesetzt ist. Aber was wird, wenn es das irgendwo nicht ist?

BTW: nachdem ich Stunden damit verbracht habe, die 'in aller Welt' verstreuten Dokumentationen, Manpages etc.pp. aufzutreiben, nach Revision histories u.ä. zu durchforsten, um (vielleicht) auf irgendwas zu stoßen, das mir das unerwartete Verhalten von Perl 5.8 erklärt, + mir schließlich Bruchstücke von wie Geschäftsgeheimnisse gehüteten mod_perl-Tutorials zusammen zu suchen, frage ich mich schon, ob ich nicht lieber ein paar MB mehr Download + Plattenplatz in Kauf genommen und dafür die Dokus des mit Wampp2 Installierten schon auf meinem Rechner vorgefunden hätte. Kann man das - vielleicht einfach ein Wahl-Paket *mit* Doku - auf den Wunschzettel schreiben?

Besten Gruß
Claus-Volker
cv
 

Postby nemesis » 16. September 2003 03:03

Gute Idee, nur, die meisten Anleitungen/Dokumentationen sind wohl doch noch auf englisch und nicht jeder versteht das umbedingt :)

Zumindest eine Art Link Liste wäre für die normalen Xampp Packete denkbar, mit kleiner Beschreibung, was einem da erwartet ;)
Ubuntu 8.04 | SMP P3 1.4 GHz | 6 GByte RegECC | 74 GByte Seagate 15k5 system | 3Ware 9550SXU-4LP with 4x 500 GByte Seagate ES2 Raid 10 data | StoreCase DE400 | PX-230A | Intel Pro/1000MT Dual PCI-X
User avatar
nemesis
AF Moderator
 
Posts: 999
Joined: 29. December 2002 13:14
Location: Ingolstadt

Hinweise/ Erkenntnisse (?) zu MODPERL

Postby Sosum » 16. September 2003 20:30

Hallo,

Ich habe mit ModPerl auch so meine Probleme gehabt...."Zwei Threads weiter unten" beschreibe ich ein noch ungelöstes Problem.

Inzwischen habe ich aber in der Doku eine *sehr* interessante Stelle gefunden: ModPerl initialisiert globale Variablen LEDIGLICH beim ersten Aufruf. Das scheint auch für INC zu gelten. Daraus habe ich abgeleitet, keine globalen Variablen mehr zu erstellen.
Auch war die Info wichtig, das das Standard-Modul, unter PERL normalerweise ::main unter Modperl sowas wie "apache::modperl::perl" ist. Aber ich lenke vom Thema ab...
Vielleicht solltest Du auch beachten, das die Einbindung von Modulen durch "use" unter MODPERL das Modul nur einmal (pro Kindprozess) tatsälich lädt. Beim nächsten Aufruf wird das Modul also direkt aus dem Hauptspeicher geholt und NICHT initialisiert. Alle Inline-Anweisungen, also Anweisungen ohne Funktionsrumpf) werden deswegen auch NICHT mehr ausgeführt. Dies ändert sich erst, wenn man den Server neu startet (-> neuer Kindprozess).

Wenn ich Dich richtig verstehe, dass möchtest Du eigentlich nur zuverlässig Module (unter MODPERL) einbinden. Da mein Server auf D: ist, aber die Seiten auf F:, war es für mich unmöglich, mittels relativer Adressierung an die Adresse meiner Module zu kommen. Daher habe ich schlichtweg absolut refernziert. Meine Lösung ist Deiner ganz ähnlich:

Code: Select all
#!/usr/bin/perl5
package heiopei;
push (@INC,"f:/web/sites/heiopei/cgi-bin/vasabi/modules");
push (@INC,"/home/strato/www/bv/www.heiopei.de/htdocs/cgi-bin/heiopei/modules");   # for server-side libs
require "vasabi.pm";

ich verwende hier "push" statt "use lib", weil ich nicht weiss, ob diese Form von USE von MODPERL auch nur einmal ausgeführt wird oder nicht. Da ich aber MODPERL nicht verwende, habe hier eigentlich schon noch das "gewhnte" <<use lib>> stehen.

Die Angabe funktionert, weil es PERL nicht kümmert, ob er ein INC Verzeichnis findet oder nicht. Man bekommt eigentlich noch nicht einmal eine Warnung darüber...


--off topic--
Letztendlich habe ich das gesamte ModPerl von meiner W2k Entwicklungsumgebung getrennt. Das aus zwei Gründen:

1. meine lokalen Skripte verursachen nicht so viel Traffic, dass ich einen schnellen PERL Interpreter bräuchte.
2. WICHTIGER ist allerdings meine Vermutung, dass MODPERL bei den meisten mietbaren Web-Server nicht (ausschliesslich) zum Zuge kommen wird. Das leite ich aus der Tatsache ab, dass aufgrund der oben genannten, gravierenden Änderungen bei weitem nicht jedes PERL Programm auf so einem System (wie erwartet) laufen würde. Das würde den Supportaufwand also zumindest erhöhen, was Geld kostet...

Grüße,
aron[/code]
Sosum
 
Posts: 24
Joined: 08. September 2003 23:08

Hinweise/ Erkenntnisse und Rätsel

Postby cv » 17. September 2003 11:16

Hallo Sosum,

ich versuche es noch zu begreifen:
ModPerl initialisiert globale Variablen LEDIGLICH beim ersten Aufruf. Das scheint auch für INC zu gelten. Daraus habe ich abgeleitet, keine globalen Variablen mehr zu erstellen.

Letzteres ist klar (ich tue es übrigens - m.E. - auch nicht); wieso heißt das aber für @INC, dass "." nur während dieser 'solitären' Initialisierung auf den Pfad des aufrufenden Scripts gesetzt wird und dann aber keineswegs da bleibt (sondern mysteriöser Weise auf "[Lw:]/wampp2" [zurück?] gesetzt wird)?
Ist der Child-Prozess vielleicht 'schon da', wenn man - wie ich - wegen der langen Erstinitialisierung von Wampp2 morgens erst mal die "Hurra-es-hat-geklappt"-Seite anguckt? - Dann wäre mein 1. Aufruf des Scripts mit dem später scheiternden "require" eigentlich der 2. Thread für den Child-Prozess; und weiter spekuliert: dann müsste ich nur warten, bis die in der httpd.conf eingestellte Anzahl der ThreadsProChild 'abgearbeitet' ist, bis mein "require" wieder arbeitet? (auch keine gute Lösung übrigens.)
Vielleicht habe ich aber auch die "Selbstbezogenheit" von "." falsch eingeschätzt, indem ich meinte, es liefere verlässlich den Ausführungsort. Wenn mod_perl das tatsächlich zu allererst ausgeführte Script als "wahres ." ansetzt, ist das vielleicht "/apache/.../start.pl" (?!).
...beachten, dass die Einbindung von Modulen durch "use" unter MODPERL das Modul nur einmal (pro Kindprozess) tatsächlich lädt. Beim nächsten Aufruf wird das Modul also direkt aus dem Hauptspeicher geholt...

(das ist ja, was man von mod_perl erwartet)
...und NICHT initialisiert. Alle Inline-Anweisungen, also Anweisungen ohne Funktionsrumpf, werden deswegen auch NICHT mehr ausgeführt

Wenn ich's recht verstehe, beträfe das nur (Bibliotheks-/Modul-) Funktionen - es sind bei mir nur "sub MyFunction{...}"-Konstrukte -, die mit $_ arbeiten (statt explizit übergebenen Argumenten: "print &MyFunction($MyValue);" etc.)?!
Wenn ich Dich richtig verstehe, dann möchtest Du eigentlich nur zuverlässig Module (unter MODPERL) einbinden.

Ja/Jein - Ich versuche z.Zt., eine bestehende Anwendung so umzuschreiben, dass sie möglichst auf jede L/Wampp-Umgebung portierbar ist. Deshalb würde ich es gern vermeiden, dass man bei jeder Installation in jede der mehrere Dutzend Script-Dateien die gerade gültigen absoluten Pfade eintragen muss; und was an solchen unabdingbar ist, stand bisher auch einfach in einer via "require './config.pl'" eingebundenen "Bibliothek". Dass das unter Apache-2/Perl-5.8/..., wie Wampp2 sie bereitstellt, nicht klappt, liegt also offenbar an mod_perl (ich hatte ja eine Wampp-spezifische httpd.conf-Einstellung in Verdacht [nun, das halbe Apache-Lehrbuch durchgeackert zu haben, ist ja auch was für's Leben :-\
Jedenfalls heißt das, dass mein Versuch, den aktuellen absoluten Pfad dynamisch zu bestimmen + dann in die "require"-Anforderungen einzutragen, letztlich unvermeidlich ist - zumindest, solange ich auf mod_perl 'vorbereitet' sein will. Und 'was Besseres als den letztes Mal skizzierten Code habe ich dafür noch nicht gefunden.
Deshalb nach allem lauten Denken doch noch eine Frage:
...meine Vermutung, dass MODPERL bei den meisten mietbaren Web-Server nicht (ausschliesslich) zum Zuge kommen wird

Heißt das vorsichtig eingeklammerte "ausschliesslich", dass ich als "User" eine Chance oder Möglichkeit hätte, zu bestimmen, ob mein Script über mod_perl 'abgearbeitet' wird (oder vielleicht über einen alternativen Standalone-Interpreter [so es den denn gibt...])? Und/oder: kann ich per Script bestimmen, ob das Programm gerade unter mod_perl läuft oder nicht?

#####

Hallo Nemesis,

...nur, die meisten Anleitungen/Dokumentationen sind wohl doch noch auf englisch und nicht jeder versteht das unbedingt


Stimmt. Und auch ich ziehe, faul wie ich bin, eine gute Übersetzung in jedem Fall vor. Allerdings wäre das letztlich ein Argument, z.B. die Wampp-Apache-httpd.conf künftig in deutscher Übersetzung einzubinden. Es muss ja nicht "FädenFürKind=126" sein, aber wenigstens die Kommentare. Könnte ja sein, dass man darin was ändern muss oder will. Will man, soll man das nicht? Hm, kann sein. Aber wozu will jemand, der nicht in den 'Interna' rumwühlen will, einen Serv.... Ah, nein. Ich frage nicht weiter. Wir begeben uns da auf ein heikles Terrain, nicht wahr?
(Um nicht zu sarkastisch zu klingen: Ich bin, wie sicherlich viele hier, der Xampp-Group dankbar für die tolle Vorarbeit. Wie weit die Leute von da aus gehen wollen - und, wenn's sein muss, Englisch lernen -, sollte man m.E. ihnen überlassen. Usability Labs können auch den Horizont verbauen.)

Besten Dank + Gruß
Claus-Volker
cv
 

Re: Hinweise/ Erkenntnisse und Rätsel

Postby Sosum » 17. September 2003 15:29

Hallo Claus-Volker,

wieso heißt das aber für @INC, dass "." nur während dieser 'solitären' Initialisierung auf den Pfad des aufrufenden Scripts gesetzt wird und dann aber keineswegs da bleibt (sondern mysteriöser Weise auf "[Lw:]/wampp2" [zurück?] gesetzt wird)?

Das mit dem Dot verstehe ich auch nicht, aber unter IIS war "." immer der Anwedungsausgangspunkt (Eigenschaften->Anwedung erstellen) und nicht das aktuelle Verzeichnis des Skripts.... Vielleicht ist es unter Apache ähnlich? Wenn ja, müsste man das ja einstellen können...

Ist der Child-Prozess vielleicht 'schon da', wenn man - wie ich - wegen der langen Erstinitialisierung von Wampp2 morgens erst mal die "Hurra-es-hat-geklappt"-Seite anguckt? - Dann wäre mein 1. Aufruf des Scripts mit dem später scheiternden "require" eigentlich der 2. Thread für den Child-Prozess;

Wie gesagt, ich verstehe MODPERLs vorgehensweise auch nicht so ganz, aber was ich weiss ist (oder glaube zu wissen), das der Child Prozess mit dem ersten Skript gestartet wird. Würde der Child Prozeß schon laufen, wenn man Wampp2 hochfährt, kämme wohl kaum zu Runtime-Fehlermeldungen à la "cannot start child prozess"...

(das ist ja, was man von mod_perl erwartet)

Ja, aber welchen Sinn es hat, "inlines" bei dem zweiten Aufruf nicht mehr zu initialisieren, verstehe ich nicht. Dadurch entstehen i.m.o. die meisten Inkompatibilitäten.

Deshalb würde ich es gern vermeiden, dass man bei jeder Installation in jede der mehrere Dutzend Script-Dateien die gerade gültigen absoluten Pfade eintragen muss; und was an solchen unabdingbar ist, stand bisher auch einfach in einer via "require './config.pl'" eingebundenen "Bibliothek".

Ja, da hast Du wirklich recht... das Problem sehe ich auch auf mich zukommen. Allerdings habe ich mir überlegt, bei einer solchen "Installation" eben ein GREP für Windows zu schreiben, das nichts anderes macht, als Verzeichnisweites "Suchen&Ersetzen". Vor dem Upload starte ich also das Progi und es dampft dann durch die CGI-Verzeichnisse und ändert den neuen, serverseitigen, absoluten Pfad auf das neue Ziel. Das ist ein kompromiss, dass ich persönlich eingehen kann.

Jedenfalls heißt das, dass mein Versuch, den aktuellen absoluten Pfad dynamisch zu bestimmen + dann in die "require"-Anforderungen einzutragen, letztlich unvermeidlich ist - zumindest, solange ich auf mod_perl 'vorbereitet' sein will. Und 'was Besseres als den letztes Mal skizzierten Code habe ich dafür noch nicht gefunden.

Ja, du hast da recht. Mir fällt in diesem Fall auch keine bessere Lösung ein.

Heißt das vorsichtig eingeklammerte "ausschliesslich", dass ich als "User" eine Chance oder Möglichkeit hätte, zu bestimmen, ob mein Script über mod_perl 'abgearbeitet' wird (oder vielleicht über einen alternativen Standalone-Interpreter [so es den denn gibt...])? Und/oder: kann ich per Script bestimmen, ob das Programm gerade unter mod_perl läuft oder nicht?

Also ich habe das eingeklammert, wei ich das natürlich nicht pauschalisieren kann -aber ich habe cgi-perl fähige Konten bei 1&1 (also Schlund & Partner), Strato und EHL-Media. Bei keinem der dreien habe ich auch überhaupt die Möglichkeit, mein Skript unter MODPERL ausführen zu lassen. Deshalb glaube ich, dass MODPERL momentan eher ein "Feature" sein kann und eben kein "STANDARD" ist. Das merkt man i.m.o. auch daran, das CGI-Skripte auf dem Webserver immer noch die "#!/bin/perl" benötigen, was ja nichts anderes ist, als der Pfad und der externe Interpreter, zu dem die Pipe gebildet wird.

##### off topic ######

Hallo Nemesis,


Auch ich ziehe, eine gute deutsche Übersetzung dem englischem vor. Es liest sich einfach schneller. Ich habe im SelfHTML Feature Artikel eine deustche Fassung einer Apache Konfigdatei gefunden: englische Schlüsselwörter, deutsche Kommentare, sehr geil. Ich habe es allerdings nicht bei mir eingebunden, weil ich zu wenig Ahnung von Apache habe und weil es bei mir momentan genauso funzt wie es soll. (N.C.A.R.S)

...nur, die meisten Anleitungen/Dokumentationen sind wohl doch noch auf englisch und nicht jeder versteht das unbedingt


Grüße,
aron
Sosum
 
Posts: 24
Joined: 08. September 2003 23:08


Return to Perl

Who is online

Users browsing this forum: No registered users and 1 guest