End of Line, CGI und der eigene Webserver

Am Ende der „Horrorwoche“ *g* stand Erleichterung – und die Gewissheit, wieder etwas gelernt zu haben.

Doch von vorn, worum gehts hier überhaupt?
Im Grunde genommen um nichts anderes, als den Versuch, auf meinem Linux (KUbuntu) einen lokalen Webserver aufzusetzen, einige ‚Virtual Hosts‘ einzurichten und darauf CGI-Scripte laufen zu lassen.

Bisher hatte ich meine ersten Gehversuche in Richtung Perl/CGI-Programmierung unter Windows unternommen, dazu das XAMPP-Paket von Apachefriends.org heruntergeladen und bin damit eigentlich auch ganz gut gefahren.
Allerdings wurde Perl ursprünglich auf und für UNIX entwickelt und kann dazu u.a. auch auf spezielle systemimmanente Möglichkeiten des Betriebssystems zurückgreifen. Kein Wunder also, dass es da so einige Unterschiede zur Windowsimplementierung der Sprache gibt.

Da ich ohnehin gelegentlich mit dem Pinguin unterwegs bin und die Scripte später ausnahmslos auf Linux-Servern laufen werden, warum also nicht gleich ein lokales Webdevelopment Environment auf meiner KUbuntu-Box einrichten? Gesagt, getan: Apache2, FastCGI und noch ein paar weitere Module nach Anleitung (http://wiki.ubuntuusers.de/Apache + https://help.ubuntu.com/community/ApacheMySQLPHP) installiert und … geht nicht!

Was diese Anleitungen nämlich verschweigen, dass, will man seine ‚Virtual Hosts‘ unter anderem Namen als ‚http://localhost/‚ laufen lassen, also z.B. unter http://testseite/, man dies auch noch in die /etc/hosts entsprechend eintragen muss. Eigentlich logisch, dennoch muss man als Newbie auf dem Gebiet erstmal drauf kommen, siehe: https://help.ubuntu.com/community/LocalhostSubdomain .

Ok, Test: es läuft … zumindest die Html-Seiten. CGI: nada.
access.log:

127.0.0.1 – – [20/Jul/2007:16:22:29 +0200] „GET /cgi-bin/script.cgi HTTP/1.1“ 500 655 „-“ „Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.5) Gecko/20061201 Firefox/2.0.0.5 (Ubuntu-feisty)“

error.log:

[Sat Jul 21 21:39:07 2007] [error] [client 127.0.0.1] Premature end of script headers: script.cgi
[Sat Jul 21 21:39:07 2007] [error] (2)No such file or directory: exec of ‚/path/to/cgi-bin/script.cgi‘ failed

Habe daraufhin alles geprüft: die Rechtevergabe der Scripte, Groß-und Kleinschreibung, ist print „Content-type: text/html\n\n“ vorhanden, laufen sie auf der Konsole, ist die Konfigurationsdatei meines ‚Virtual Host‘ korrekt … habe schlichtweg nahezu alles auf Fehler abgeklopft, sogar durch den größten Teil der Apache-Doku http://httpd.apache.org/docs/2.0/ hab ich mich geschlagen: ohne Erfolg.

Eine der falschen Fährten, der ich gefolgt bin, war der Gedanke, dass die Ausführung scheitert, weil der Webserver als User: www-data in der Gruppe: www-data läuft und ich als User: industrie13 in industrie13 nicht genügend Rechte hab, und deshalb zusätzlich suEXEC einrichten müsse.

Desweiteren die Befürchtung, dass die Probleme daher rühren konnten, dass ich meine ‚Virtual Hosts‘ im Homeverzeichnis eingerichtet habe und nicht standardmäßig in /var/www/.
Am Rande: Der Grund dafür, dass ich den DocumentRoot ind Homeverzeichnis gelegt habe, war der, dass ich beim Basteln und Scripte schreiben mit normalen Userrechten arbeiten kann, und nicht umständlicherweise jedesmal auf alles als „root“ zugreifen muss.

Zu den Kuriositäten gehörte auch, dass ein Script bei Aufruf in der Konsole angab, dass es ein Modul nicht finden konnte, welches im selben Ordner wie es selbst lag
Fehlermeldung:

industrie13@linworks:~$ perl /path/to/cgi-bin/script.cgi
Content-type: text/html

<h1>Software error:</h1>
<pre>Can’t locate Modul.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.8.8 /usr/local/share/perl/5.8.8 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .) at /path/to/cgi-bin/script.cgi line 24.
BEGIN failed–compilation aborted at /path/to/cgi-bin/script.cgi line 24.
</pre>
<p>
For help, please send mail to this site’s webmaster, giving this error message
and the time and date of the error.

</p>
[Fri Jul 20 23:11:24 2007] script.cgi: Can’t locate Modul.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.8.8 /usr/local/share/perl/5.8.8 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .) at /path/to/cgi-bin/script.cgi line 24.
[Fri Jul 20 23:11:24 2007] script.cgi: BEGIN failed–compilation aborted at /path/to/cgi-bin/script.cgi line 24.

wobei allerdings der Punkt „.“ des @INC-Listings eindeutig implizierte, dass eben auch der Ordner des aufrufenden Scriptes durchsucht wurde.

Der Auflösung näher kam ich erst, als ich das Script ohne vorangestelltes „perl“ in der Konsole aufrief:

industrie13@linworks:~$ /path/to/cgi-bin/script.cgi
bash: /path/to/cgi-bin/script.cgi: /usr/bin/perl^M: bad interpreter: No such file or directory

Logisch dass Linux den Interpreter „perl^M“ nicht findet, da es ihn nicht gibt. Aber wo zum Teufel kommt dieses „^M“ her???
Etwas googlen brachte endlich Klarheit: als End of Line (EOL) bzw. Zeilenumbruch verwendet Windows/DOS die Sequenz „\r\n„, während UNIX standardmäßig „\n“ schreibt.
Frühere bzw. konsolenbasierte Linux-Editoren wie z.B. vi kamen mit den Windows/DOS – Zeilenumbrüchen nicht klar und zeigten stattdessen eben erwähntes „\r“ als ’nonprintable Zeichen‘ „^M“ an.

Ein cat -v <dateiname> mit meinem Script gab es mir denn auch entsprechend „^M“ am Ende jeder Zeile aus. Soweit zum Thema Fehlerquelle.
Ein „View/View EOL Markers“ auf meinen KomodoEdit (nebenbei, ein wunderbarer freier CrossPlattform und MultiLanguage Code Editor mit Autovervollständigung, Syntaxcheck usw) bestätigte mir das nochmal.
Mit Find&Replace alle Windows-EOLs in UNIX-Standardumbrüche umgewandelt und siehe da: es lief wunderbar, keine Fehlermeldungen, kein „premature end of scriptheaders„, kein irgendwas :D.

Blieb nur noch eine Frage: das selbe Script mit seinen Windows-EOLs lief schoneinmal wunderbar auf meinem Webspace, dem auch ein Linux-Server zugrunde liegt … und zwar, ohne dass ich die Zeilenumbrüche abändern musste. Desweiteren: viele Scripte werden unter Windows geschrieben und dann einfach auf Linux-Server hochgeladen, ohne dass es zu irgendwelchen Problemen kommt. Haben diese Webspaceanbieter also ihre CGI-Ausführung „toleranter“ für den Umgang mit Windows-Zeilenumbrüchen konfiguriert, bzw. ich meine CGI-Implementierung nur noch nicht richtig angepasst???

Beides ist falsch.
Es ist vielmehr so, dass die Scripte via FTP im ASCII-Mode auf den Server geladen werden. Dabei werden automatisch die Zeilenumbrüche zwischen den verschieden System konvertiert. Wer mehr dazu erfahren möchte, der sei auf http://en.wikipedia.org/wiki/End_of_line verwiesen.

Soviel zu meiner Story, eigene CGI-Scripte auf einem lokal eingerichteten Webserver laufen lassen zu wollen. Vielleicht kann sie dem ein oder anderem helfen, ähnliche Fehler leichter zu lokalisieren und dementsprechend schneller voranzukommen.

In diesem Sinne erstmal:
End of Line!!!

Einen Kommentar schreiben