User since
2006-01-21
79
Artikel
BenutzerIn
Hi,
ich verzweifle langsam. Ich versuche die Ausgabe eines Programms live abzufangen, doch irgendwie bekomme ich es nicht richtig hin. Wenn ich mit dem unten ausgeführten Skript versuche, die Daten abzufangen, bekomme ich diese erst, wenn das Programm beendet ist.
Ich hoffe ihr könnt mir auf die Sprünge helfen.
MfG XiCoN-FJS-
Hier das "Abfrage-Skript":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use strict;
use warnings;
use Diagnostics;
use open ':utf8';
use open ':std';
use IPC::Open3;
$| = 1;
my $pid = open3( undef, my $read, undef, './test' );
while ( my $line = <$read> )
{
print $line;
}
Und hier das Programm, welches abgefragt wird:
(gcc -o test test.c)
[cpp]#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("test1\n");
sleep(5);
printf("test2\n");
sleep(10);
printf("test3\n");
return 0;
}[/cpp]
User since
2003-08-04
14371
Artikel
ModeratorIn
So funktioniert es bei mir:
use strict;
use warnings;
$| = 1;
open my $read, 'test.pl |';
while ( my $line = <$read> ){
print $line;
}
und die test.pl:
$|++;
for(0..7){
print "$_\n";
sleep 1;
}
Man beachte das
$|++ in test.pl. Ohne das habe ich den gleichen Effekt gehabt wie Du.
Hier läuft WinXP mit ActivePerl 5.8.8. Vielleicht gibt's da auch von OS zu OS Unterschiede...
User since
2005-08-17
1420
Artikel
BenutzerIn
Eher nicht. Der open3 kommt erst zurück, wenn das aufgerufene Programm beendet wurde. Von daher kann das nicht klappen.
Die Pipe ist hier denke ich der richtige Weg. Allerdings würde ich hier die 3-Argument-Form benutzen:
open( my $fh, '-|', 'test.pl')
or die "Error, cannot start command: $!";
User since
2003-08-04
14371
Artikel
ModeratorIn
Hier bringt auch die 3-Arg-Form von open nichts. Das Wichtige (neben der Pipe) ist das autoflush im ausgeführten Programm - jedenfalls hier auf dem oben genannten System...
User since
2005-08-17
1420
Artikel
BenutzerIn
Ja, hier bringts nichts. Aber wenn man sichs mal generell angewöhnt, kanns sicherlich nicht schaden ;)
User since
2006-01-21
79
Artikel
BenutzerIn
Danke erstmal für die Antworten, aber ich habe ja extra den Quellcode des C-Programms hinzugefügt, da es genau damit nicht geht, und nicht mit der von reene eingebrachten (und nicht vorhandenen) "test.pl".
Und das Problem ist, dass die "test.c" nur ein Beispiel ist, die zeigen soll, was genau nicht funktioniert, doch das original-Programm ist nicht änderbar.
Also das Programm, von dem der output ausgelesen werden soll, ist statisch, nicht veränderbar. Und wenn man das Programm "test.c" mal kurz kompiliert, wird man sehen, dass es auch wunderbar an sich funktioniert, d.h. dass die Ausgaben so zeitlich versetzt kommen, wie es programmiert ist. Doch wenn ich das Programm durch Perl "parsen" lassen, also den output abfange, bekomme ich immer erst die Ausgaben, wenn das Programm beendet ist.
Ich hoffe ihr versteht, was ich meine.
MfG XiCoN-FJS-
User since
2005-08-17
1420
Artikel
BenutzerIn
Das Problem scheint dann wohl zu sein, dass dein Programm wohl erst beim Beenden seinen Ausgabepuffer flusht und vorher gar nichts ausgibt...
Wie man das nun lösen kann, keine Ahnung.
User since
2006-01-21
79
Artikel
BenutzerIn
nepos+2008-01-18 16:43:47--Das Problem scheint dann wohl zu sein, dass dein Programm wohl erst beim Beenden seinen Ausgabepuffer flusht und vorher gar nichts ausgibt...
Wie man das nun lösen kann, keine Ahnung.
"Und wenn man das Programm "test.c" mal kurz kompiliert, wird man sehen, dass es auch wunderbar an sich funktioniert, d.h. dass die Ausgaben so zeitlich versetzt kommen, wie es programmiert ist."
Es funktioniert ja auf der Konsole wunderbar, deshalb scheint es mir so, als wenn Perl Probleme damit hat, dieses "live" abzufangen. Oder liege dich damit falsch?
MfG XiCoN-FJS-
User since
2004-07-19
1776
Artikel
HausmeisterIn
Vielleicht musst Du ja auch in Deinem C Programm die Ausgabe an einigen Stellen flushen (
fflush(stdout)), oder auf Zeilenpufferung einstellen (
setvbuf(stdout, (char *)NULL, _IOLBF, 0)).
In der Regel ist die Standardausgabe zwar schon auf Zeilenpufferung konfiguriert, aber das ist je nach C-Runtime vielleicht anders wenn das Ausgabeziel kein Terminal ist.
When C++ is your hammer, every problem looks like your thumb.