Thread externes Programm starten und gleich zurückkehren (2 answers)
Opened by sirius at 2012-01-06 19:44

sirius
 2012-01-06 19:44
#155295 #155295
User since
2012-01-06
25 Artikel
BenutzerIn
[default_avatar]
Hallo,

ich möchte folgendes erreichen:
Im Browser kann man eine Datei hochladen. Diese Datei bedarf einer längeren Verarbeitung nach dem upload. Deswegen wird ein Programm / Script gestartet (afterUpload.pl) welches im Hintergund die Verarbeitung übernimmt, wärend die index.cgi mit einer fertigen Seite zurückkommt. Damit der User jetzt auch den Status der Verarbeitung sieht, soll im Browserfenster ein html-object eingebaut werden, welches eine html-Seite vom Script showUpload.cgi bekommt und sich so ca. alle 5 Sekunden aktualisiert. Ich habe schon lange im Netz gesucht und bereits zahlreiche Vorschläge ausprobiert. Die einfachen Kommandos system, exec, qx funktionieren so alleine nicht. Wenn ich den Prozess teile (fork) und die Ausgabe-pipe schließe "close(STDOUT)" dann komme ich schon recht weit, ausser dass der völlig neue html-Request zu showUpload.cgi erst zurückkehrt, wenn afterUpload.pl fertig ist.
Wichtig ist noch, dass kein javascript im Spiel sein darf.

Konnte mir jemand folgen? ;-)


ich habe es mal im Code soweit wie möglich runtergebrochen
zuerst die index.cgi:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/perl

use CGI;

my $cgi=new CGI();

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

if ($cgi->param()) {
        #button gedrückt = upload von Datei
        
        #so, jetzt möchte ich ein programm starten und gleich wieder hier zurückkehren
        #alles getestet:
        # system('perl afterupload.pl');
        # exec('perl afterupload.pl');
        # qx(perl afterupload.pl);
        # open(f,'|perl afterupload.pl');
        
        #ganz gut klappt eben
        my $pid=fork();
        unless (defined $pid) {
                die "no ressources for upload available"
        } elsif ($pid==0) {
                close(STDOUT); # ganz wichtig!!!
                exec("perl afterUpload.pl");
                exit(0);
        } else {
                print q(<html>
                                 <head />
                                 <body>
                                  so weit, so gut....<br>
                                  <object data="showUpload.cgi" type="text/html" width="100%" height="100%"></object>
                                 </body>
                                </html>);
        }
} else {
print <<'EOF'
<html>
 <head/>
 <body>
  <form method="post" action="index.cgi">
   <button type="submit" name="test" value="x">tu so als ob upload</button>
  </form>
 </body>
</html> 
EOF
}

diese ruft ja, die afterupload.pl auf:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl

# so, hier passiert jetzt recht viel und lange


for (my $i=0; $i<10; $i++) {
        
        # Status der Datenverarbeitung speichern (normalerweise in Datenbank und natürlich umfangreicher)
        open(fh,'>test.txt') or die;
        print fh $i; 
        close(fh);
        sleep(5);
}


und dann noch die showUpload.cgi:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/perl

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

my $r = open(fh,'<test.txt');

if ($r) {
        my $i = <fh>;
        close(fh);

        print qq(<html>
        <head>
                <meta http-equiv="refresh" content="5">
        </head>
        <body>
        i = $i
        </body>
        </html>
        );
} else {
        print qq(<html>
        <head>
                <meta http-equiv="refresh" content="5">
        </head>
        <body>
        file missing
        </body>
        </html>
        );
}

im Browser ruft man jetzt die index.cgi auf. Wenn man jetzt den Button drückt, sollte auf der nächsten Seite von 0 bis 9 hochgezählt werden, was aber nicht passiert.

weitere Infos
Server: Apache 2.2.16 auf debian
Perl $]: 5.010001
bis vor Weihnachten funktionierte es mit open(fh,'|perl ...'); und ohne fork auch einwandfrei. anscheinend wurde der Serve auf den ich keinen Einfluss habe geupdatet/verändert

Kurz vorm Abesnden kommt man ja noch auf Ideen. Ich habe obiges Beispiel nochmal auf einem anderen Server probiert (debian mit lighttpd 1.4 und selben perl $]). Da funktioniert es wie gewünscht.

Ratlos....


Edit: Jetzt, wo ich mir das ganze noch (schon wieder) mal durch den Kopf habe gehen lassen, liegt es wohl an Apache. Vielleicht ist da etwas falsch eingestellt. Ich kann da leider nur nix ändern.
Was ich noch ergänzen möchte: Ich konnte auch mit dem Apache das ShowUpload-Script in einem extra Tab des Browsers aufrufen (das klappt auch bei meinen Originalen) und die Seite wurde korrekt angezeigt.

Vielen Dank für jeden Hinweis
Last edited: 2012-01-06 22:13:40 +0100 (CET)

View full thread externes Programm starten und gleich zurückkehren