Alain: cgi mit exit; beenden-konzequenz?

Moin, ich wollte wissen ob ein skript mit exit beendet werden darf,obwohl z.B. eine vorher geöffnete datei durch dieses cgi noch nicht geschlossen wurde? Wenn nicht welche konzequenz hätte dies eventuell, wenn dieses cgi nächstes mal aufgerufen würde? Grüsse vom Alain--

  1. Moin,
    ich wollte wissen ob ein skript mit exit beendet werden darf,obwohl
    z.B. eine vorher geöffnete datei durch dieses cgi noch nicht geschlossen wurde?
    Wenn nicht welche konzequenz hätte dies eventuell,
    wenn dieses cgi nächstes mal aufgerufen würde?

    Keine.
    Dateien werden automatisch geschlossen.
    exit ist aber wohl eher für nicht-CGI Anwendungen gedacht um einen Fehlercode zurück zu geben.

    Also besser vermeiden und eine saubere Programmstruktur befolgen.

    Struppi.

    1. hallo struppi,

      Keine. Dateien werden automatisch geschlossen. exit ist aber wohl eher für nicht-CGI Anwendungen gedacht um einen Fehlercode zurück zu geben.

      Also besser vermeiden und eine saubere Programmstruktur befolgen.

      ok,aber in den meisten cgi's sieht man dieses exit irgendwo. Also ist exit nicht unbedingt notwendig,wenn im cgi 100% einen true wert gefunden wird? Oder wäre allenfalls "EOF" am Schluss für das richtige beenden eines cgi's zuständig? Das mit "return" kapier ich nähmlich nicht ganz. Grüsse vom Alain

      1. hallo struppi,

        Keine.
        Dateien werden automatisch geschlossen.
        exit ist aber wohl eher für nicht-CGI Anwendungen gedacht um einen Fehlercode zurück zu geben.

        Also besser vermeiden und eine saubere Programmstruktur befolgen.

        ok,aber in den meisten cgi's sieht man dieses exit irgendwo.
        Also ist exit nicht unbedingt notwendig,wenn im cgi 100% einen true wert gefunden wird?

        Da widerrum kapier ich nicht ganz ;-)

        exit ist einfach unsauber wenn man einfach nur ein Programm beenden will.
        Wie gesagt es sollte für den Fehlerfall verwendet werden.

        Oder wäre allenfalls "EOF" am Schluss für das richtige beenden eines cgi's zuständig?

        Nicht unbedingt.

        Das mit "return" kapier ich nähmlich nicht ganz.

        Wieso das du machst eine sub und kehrst zurück mit return und das an jeder Stelle.

        #!/usr/bin/perl -w

        if(main() != 0)
        {
           print "Es trat ein Fehler auf!";
        }
        else
        {
           print "Alles ok!";
        }

        sub main
        {
            if(alles_ok() == 0) return 0;
            #es trat ein fehler auf
            return 1;
        }

        sub alles_ok
        {
           # prüfe Werte und gib bei Erfolg 0 zurück.
           return 0;
        }

        So in etwa, da brauchste kein exit. Zumal ion CGI programen exit gefährlich sein kann, da du dann immer sicher sein musst, das bereist ein Header ausgegeben wurde.

        Struppi.

      2. Hi Alain,

        Also ist exit nicht unbedingt notwendig,wenn im cgi 100% einen true wert gefunden wird?

        "exit" beendet den Lauf des Perl-Skripts und setzt den Return-Code an den Aufrufer.
        Was der aufrufende Webserver mit diesem Wert anfangen kann, das sei in diesem Kontext dahin gestellt; die CGI-Spezifikation sagt nichts Spezielles hierüber aus.

        Oder wäre allenfalls "EOF" am Schluss für das richtige beenden eines cgi's zuständig?

        Was meinst Du mit "EOF"? Ein Befehl dieser Art ist mir nicht bekannt.
        Falls das Skript das Ende des Quelltextes erreicht, dann wird es allerdings ebenfalls beendet.

        "exit" an der passenden Stelle kann Dir ersparen, für die Alternative ein riesiges, unübersichtliches "if"-Konstrukt aufzubauen.
        Ich halte das kontrollierte Herausspringen aus Kontrollstrukturen keineswegs für "unsauber" - geeignet angewendet und hinreichend gut dokumentiert macht es den Quelltext sogar deutlich lesbarer.

        Das mit "return" kapier ich nähmlich nicht ganz.

        "return" setzt ebenfalls den Returncode, genau wie "exit". Aber es beendet nur die aktuelle Kontrollfluß-Ebene, nicht jedoch alle (wie exit). Wenn Du innerhalb einer Funktion "return" ausführen läßt, dann wird das Skript an der Stelle fortgesetzt, wo die zuvor aktive Funktion aufgerufen wurde - genauso, als hätte der Perl-Interpreter das Ende des äußersten Blocks dieser Funktion erreicht.

        Was insbesondere bedeutet: Innerhalb des Hauptprogramms haben "return" und "exit" dieselbe Wirkung, weil dort nur eine Kontrollfluß-Ebene 'offen' ist.

        Viele Grüße
              Michael

        --
        T'Pol: I apologize if I acted inappropriately.
        V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
        1. "exit" an der passenden Stelle kann Dir ersparen, für die Alternative ein riesiges, unübersichtliches "if"-Konstrukt aufzubauen.

          Denn zusammenhang versteh ich nicht. Wenn ich irgendwo ein exit einbaue, dann schreib ich keine if-Abfragen mehr?

          Solte es zu so einem Fall kommen, dann ist wohl irgendwo der Wurm im Design.

          Ich halte das kontrollierte Herausspringen aus Kontrollstrukturen keineswegs für "unsauber" - geeignet angewendet und hinreichend gut dokumentiert macht es den Quelltext sogar deutlich lesbarer.

          Das Herrauspringen ist auf keinen Fall unsauber, aber das Beenden des Programmes an einer willkürlichen Stelle ist unsauber, zumal bei CGI Programmen, da der Client auf eine sinnvolle Ausgabe wartet.

          Das mit "return" kapier ich nähmlich nicht ganz.

          "return" setzt ebenfalls den Returncode, genau wie "exit". Aber es beendet nur die aktuelle Kontrollfluß-Ebene, nicht jedoch alle (wie exit). Wenn Du innerhalb einer Funktion "return" ausführen läßt, dann wird das Skript an der Stelle fortgesetzt, wo die zuvor aktive Funktion aufgerufen wurde - genauso, als hätte der Perl-Interpreter das Ende des äußersten Blocks dieser Funktion erreicht.

          Was insbesondere bedeutet: Innerhalb des Hauptprogramms haben "return" und "exit" dieselbe Wirkung, weil dort nur eine Kontrollfluß-Ebene 'offen' ist.

          Probier's mal:
          #!/usr/bin/perl

          return "TEST";
          Can't return outside a subroutine at test.pl line 7.

          selbst ohne strict und Warnung.

          Struppi.

          1. Moin!

            "exit" an der passenden Stelle kann Dir ersparen, für die Alternative ein riesiges, unübersichtliches "if"-Konstrukt aufzubauen.

            Denn zusammenhang versteh ich nicht. Wenn ich irgendwo ein exit einbaue, dann schreib ich keine if-Abfragen mehr?

            Denk dir sowas in der Art:

            if (es_reicht_den_header_304_zu_senden)
            {
              gib_304_an_browser();
              exit;
            }

            // Hier Ausgabe der kompletten Seite über viele viele Programmzeilen Here-Dokument.

            Du kannst auf das Exit verzichten, und mit else die aktuellere Seite ausgeben. Dann hast du am Ende des Skripts zwingend darauf zu achten, das mehr oder weniger sinnlos erscheinende "}", welches den Else-Block abschließt, nicht zu löschen. Außerdem mußt du, wenn du wirklich ernsthaft einrückst, den gesamten Else-Block einrücken. Das mag bei einem simplen Skript irrelevant sein (außer dass es die Datei aufplustert), aber je nach Menge der Einrückungszeichen je Stufe wird es irgendwann, wenn ein Block sich einrückungsmäßig der rechten Bildschirmhälfte nähert, kritisch. Da spart man dann lieber eine Ebene ein, und gut ist.

            Es ist auch für die Übersichtlichkeit besser, wenn ein Block nicht nahezu das gesamte Skript umfaßt.

            - Sven Rautenberg

            --
            "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
            1. Moin!

              "exit" an der passenden Stelle kann Dir ersparen, für die Alternative ein riesiges, unübersichtliches "if"-Konstrukt aufzubauen.

              Denn zusammenhang versteh ich nicht. Wenn ich irgendwo ein exit einbaue, dann schreib ich keine if-Abfragen mehr?

              Denk dir sowas in der Art:

              if (es_reicht_den_header_304_zu_senden)
              {
                gib_304_an_browser();
                exit;
              }

              // Hier Ausgabe der kompletten Seite über viele viele Programmzeilen Here-Dokument.

              Machst du sowas?
              Ich nicht. entweder ich bau die Ausgabe in verschiedenen subs zusammen und/oder verwende CGI.pm oder HTML::Template. Darüber hinaus gibt's noch dieses inline Perl.

              Ausserdem, wenn's nur darum geht einen Header zu senden, ist exit durchaus legitim, dann würd ich sogar das exit in der Funktion verstecken, wenn klar ist, dass nach einem entsprechendem header keine Daten mehr kommen müssen

              Also so:
              gib_304_an_browser() if es_reicht_den_header_304_zu_senden();

              Aber wie gesagt, das verwenden von exit sollte wohlüberlegt sein. Ich habe nie behauptet, dass es nicht verwendet werden darf. Wenn es dir oder dem OP Spaß macht ein exit (das nebenbei, wenn schon denn schon einen Code mitgeben sollte) zu verwenden, spricht nichts dagegen. Man sollte sich nur im klaren sein, das es quasi einen Fluß abbricht und unter Umständen in einem großen Projekt schwer zu pflegen sein kann, wenn an verschiedenen Stellen das Programm abgebrochen wird. Da ein CGI Programm eben eine saubere Ausgabe bringen muss.

              Struppi.

              1. Moin!

                Machst du sowas?

                Ja, durchaus. Wenn auch nicht in Perl, sondern in PHP.

                [...] Wenn es dir oder dem OP Spaß macht ein exit (das nebenbei, wenn schon denn schon einen Code mitgeben sollte) zu verwenden, spricht nichts dagegen. Man sollte sich nur im klaren sein, das es quasi einen Fluß abbricht und unter Umständen in einem großen Projekt schwer zu pflegen sein kann, wenn an verschiedenen Stellen das Programm abgebrochen wird. Da ein CGI Programm eben eine saubere Ausgabe bringen muss.

                Funktionen haben eigentlich kein exit zu verwenden, außer es tritt ein schwerwiegender Fehler auf - dann wird aber in der Regel vom Interpreter selbst schon abgebrochen.

                Exit als Befehl im Hauptprogrammfluss unterzubringen kann Dinge relativ einfach abkürzen. Schließlich heißt die Sprache nicht Pascal, man kann durchaus auch sinnvoll aus Blöcken herausspringen. Du verteufelst ja schließlich die return-Anweisung auch nicht - die macht ja grundsätzlich nichts anderes.

                - Sven Rautenberg

                --
                "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
                1. hehe, schnell noch einen draufsetzen bevor er verschwindet ;-)

                  Exit als Befehl im Hauptprogrammfluss unterzubringen kann Dinge relativ einfach abkürzen. Schließlich heißt die Sprache nicht Pascal, man kann durchaus auch sinnvoll aus Blöcken herausspringen. Du verteufelst ja schließlich die return-Anweisung auch nicht - die macht ja grundsätzlich nichts anderes.

                  ich verteufel exit nicht.
                  return springt zurück, daher kannst du es nicht im Hauptblock verwenden, also macht es was anderes.
                  Und deine Aussage  "... kann Dinge relativ einfach abkürzen.. " deutet meines erachtens schon daraufhin, dass man prinzipiell ein ungutes Gefühl hat, aber um etwas abzukürzen benuzt man es halt.
                  Ei, warum dann nit? wie man hier sagt.

                  Struppi.

        2. Moin,

          Was meinst Du mit "EOF"? Ein Befehl dieser Art ist mir nicht bekannt.

          EOF hab ich in einem bereits geschriebenen script gesehen ganz unten, ich dachte das soll eventuell end of if bedeuten...wusste nicht dass dies nix mit perlsprache zu tun hat.Hätte aber sein können.

          Falls das Skript das Ende des Quelltextes erreicht, dann wird es allerdings ebenfalls beendet.

          das meinte ich mit EOF ...

          "exit" an der passenden Stelle kann Dir ersparen, für die Alternative ein riesiges, unübersichtliches "if"-Konstrukt aufzubauen.

          verstehe...

          "return" setzt ebenfalls den Returncode, genau wie "exit". Aber es beendet nur die aktuelle Kontrollfluß-Ebene, nicht jedoch alle (wie exit). Wenn Du innerhalb einer Funktion "return" ausführen läßt, dann wird das Skript an der Stelle fortgesetzt, wo die zuvor aktive Funktion aufgerufen wurde - genauso, als hätte der Perl-Interpreter das Ende des äußersten Blocks dieser Funktion erreicht.

          also ist "return;" dasselbe wie exit; nur eben für eine bestimmte zuvor aufgerufene funktion. wodurch aber das script selbst nicht komplett ausgeschaltet wird? Richtig?

          Ich war auf das exit; problem gestossen,weil ich bei einer "html" Ausgabe im cgi das exit gesetzt hatte und die log datei desshalb nicht geschrieben wurde,weil das script ja beendet wurde durch diese "html" ausgabe. Im Prinzip bräuchte ein cgi also auch kein exit; wenn es sauber geschrieben wurde,aber ich frage mich trotzdem,warum bei all den free cgi's irgendwo und wenn nur am Schluss des cgis ein exit oder exit(0); stehen muss?!

          Grüsse vom Alain

          1. also ist "return;" dasselbe wie exit; nur eben für eine bestimmte zuvor aufgerufene funktion.
            wodurch aber das script selbst nicht komplett ausgeschaltet wird? Richtig?

            Nicht ganz.
            exit beendet das Programm und return beendnet eine Funktion.

            Ich war auf das exit; problem gestossen,weil ich bei einer "html" Ausgabe im cgi das exit gesetzt hatte und die log datei desshalb nicht
            geschrieben wurde,weil das script ja beendet wurde durch diese "html" ausgabe.

            Wie gesagt, bei CGI Programmen exit zu verwenden ist unsauber und gefährlich, da du ganz genau gucken musst, das auch eine vernünftige ausgabe beim CLient ankommt.

            Im Prinzip bräuchte ein cgi also auch kein exit; wenn es sauber geschrieben wurde,aber ich frage mich
            trotzdem,warum bei all den free cgi's irgendwo und wenn nur am Schluss des cgis ein exit oder exit(0); stehen muss?!

            Das muss bestimmt nicht da stehen. Sondern es steht da. Warum, weiss der Teufel. liegt aber vernutlich an der Nachlässigkeit der Programmierer.

            Struppi.