Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]266[/thread]

IPC::Open3: aus einem CGI-Script heraus aufrufen

Leser: 1


<< >> 10 Einträge, 1 Seite
steffenw
 2004-05-25 00:14
#2582 #2582
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Das folgende Script funktioniert soweit gut, wenn ich es aus einem Script starte, welches ich über die Windows-Eingabeaufforderung starte.

Es funktioniert nicht mehr, wenn ich es aus einem CGI-Script heraus aufrufe. Das war eigentlich der Sinn. Ich habe dann lauter schlafende Prozesse herumhängen. Irgendwie können die nichts ausgeben oder so etwas. Sie enden auch nicht allein.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
use IPC::Open3;
my $pid = open3(\*IN, \*OUT, \*OUT, 'perl', '-c', 'script.pl') or die $!;
close IN;
my $error = <OUT>;
unless ($error =~ /OK/)
{ $error .= $_ while(<OUT>);
 close OUT,
 croak $error;
}
close OUT;
# wenn ich hierher komme, geht ein Start von script.pl nicht schief

Das Problem, was ich damit lösen wollte ist, daß ich eine sehr umfangreiche Datenbankabfrage im Script aufrufen muß, die länger dauert, als der Timeout des Webservers. Also wollte ich Script teilen und den datenbankabfragenden Teil mit open3 zum Test compilieren und bei Erfolg mit Win32::Process starten.

Der gestartete Prozeß schreibt dann in ein File, in dem das Ergebnis steht.

Das CGI-Script lasse ich zyklisch die Seite aktualisieren und umgehe so den Timeout. Wenn es das Ergebnisfile sieht, stellt es den Fileinhalt dar und schaltet die Aktualisierung wieder ab.

Ich habe das so laufen, es funktioniert, nur wenn ich einen Syntaxfehler im Script habe, welches das File erstellt, dann wartet das CGI-Script ewig, nie kommt eine Fehlermeldung und das File wird nie erstellt. Das wollte verhindern, indem ich das Script, welches zum Windows-Prozeß wird, vorher compiliere.

Aber gleich mal nachgefragt: Mache ich mir da zu viel Aufwand oder welche andere Lösungsansätze gibt es für so etwas. Den Timeout abschalten ist aber keine Lösung.\n\n

<!--EDIT|steffenw|1085430063-->
$SIG{USER} = sub {love 'Perl' or die};
steffenw
 2004-05-26 00:12
#2583 #2583
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
:( Oooooorrrrrr schade, nicht eine Antwort.

Hoffentlich liegt es nicht daran, daß ich OPC anstatt IPC in der Überschrift geschrieben habe. Hat wirklich noch keiner mit Open3 gearbeitet?
$SIG{USER} = sub {love 'Perl' or die};
Strat
 2004-05-26 00:15
#2584 #2584
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
daran sind meistens die rechte schuld, nicht IPC::Open3... validieren kannst du es, indem du es mal mit system ausfuehrst...
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
steffenw
 2004-05-26 00:27
#2585 #2585
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Na gut, Rechte, ich arbeite unter Windows und da ist da nicht viel los, weiß nicht, ob ich in die Richtung denken muß.

Aber system kann ich ja mal ausprobieren. Ich habe open3 genommen, weil Perl beim Compilieren die Ausgaben auf STDERR bringt.
$SIG{USER} = sub {love 'Perl' or die};
esskar
 2004-05-26 05:56
#2586 #2586
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
hmm...
ich versteh eigentlich nicht wirklich dein Problem!
Ist IPC::Open3 dein Problem, oder ist Win32::Process dein Problem?

Wann startest du den Win32::Process und für was ist das perl -c für dich genau gut?

wenn du nicht IPC::Open3 benutzen willst,
kannst du auch pipen!

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my $handle;
if(open($handle, "perl -c script.pl 2> stderr |")
{
close($handle);
}

if(-e "stderr")
{
if(open($handle, "stderr"))
...
}


aber wahrscheinlich brauch man das alles nicht;
also - lass mich dich verstehen! :)
steffenw
 2004-05-26 13:28
#2587 #2587
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Also Win32::Process nehme ich, um das Hintergrundscript zu starten.

Wenn es dieses aber nicht gibt oder es wegen einem Syntaxfehler abbricht. Dann bekomme ich das aus Win32::Process nicht heraus, kann also keine Fehlermeldung generieren.

Also wollte ich das Script für den Hintergrundprozeß vorher compilieren, also sehen, was auf STDERR zurückkommt. "Syntax OK" sagt mir, daß es geklappt hat, alles andere ist dann ein Fehler.

Das mit der Umleitung
Code: (dl )
open($handle, "perl -c script.pl 2> stderr |")
wußte ich nicht, wie das geht. Gleich auf STDOUT umleiten geht wohl nicht? Das wäre optimal. Muß es ein File sein?
$SIG{USER} = sub {love 'Perl' or die};
esskar
 2004-05-26 13:45
#2588 #2588
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
[quote=steffenw,26.05.2004, 11:28]Gleich auf STDOUT umleiten geht wohl nicht? Das wäre optimal. Muß es ein File sein?[/quote]
Code: (dl )
open($handle, "perl -c script.pl 2>\&1 |")


muss kein file sein!
steffenw
 2004-05-26 16:55
#2589 #2589
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
:) Sieht gut aus, danke @Esskar.

hier die Methode aus dem Modul:
Code: (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
sub ProcessStart
{ my ($self, %arg) = @_;
 $arg{perl} or croak qq~Argument "perl" ist nicht angegeben.~;
 $arg{script} or croak qq~Argument "script" ist nicht angegeben.~;
 $arg{arg} ||= [];
 ref $arg{arg} eq 'ARRAY' or croak qq~Argument "arg" ist keine Arrayreferenz.~;
 my $cmd = "$arg{perl} -c $arg{script}";
 open(PIPE, "$cmd 2>\&1 |")   # Rückgabewert = Prozeßnummer
 or croak qq~"$cmd", Compilierung fehlgeschlagen:\n$!~;
 my @line = <PIPE>;
 close PIPE;
 @line == 1 and $line[0] =~ /OK/
 or croak "Compilierung fehlgeschlagen:\n" . join '', @line;
Win32::Process::Create
( my $process,
$arg{perl},
join(' ', 'perl', $arg{script}, @{$arg{arg}}),
0,
DETACHED_PROCESS,
'.',
) or croak Win32::FormatMessage Win32::GetLastError;
 my $pid = $process->GetProcessID();
 push @line, qq~Prozeß "$$" hat Hintergrundprozeß "$pid" gestartet und wartet auf Ergebnis oder Fehler.~;
 return wantarray ? ($process, \@line) : $process;
}
\n\n

<!--EDIT|steffenw|1085579172-->
$SIG{USER} = sub {love 'Perl' or die};
esskar
 2004-05-26 17:05
#2590 #2590
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
heißt, es läuft jetzt?
steffenw
 2004-05-26 17:40
#2591 #2591
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Jaaaaaaa, danke. Läuft ideal!!!!
$SIG{USER} = sub {love 'Perl' or die};
<< >> 10 Einträge, 1 Seite



View all threads created 2004-05-25 00:14.