Schrift
[thread]7837[/thread]

Ausgabe "realtime" auslesen



<< >> 8 Einträge, 1 Seite
aedu0
 2006-03-28 23:15
#64140 #64140
User since
2006-03-28
1 Artikel
BenutzerIn
[default_avatar]
Salü Zusammen

Ich möchte ein CLI-Skript, welches etwas ausgibt, in einem zweiten CLI-Skript ausführen und die Ausgaben "Realtime" darstellen.

Ich habe nun diese zwei (Beispiel-)Skripte:

skript1.pl
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl -w
use strict;
my $i = 0;

while ($i < 10) {
print "bla\n";
sleep(1);
$i++;
}


skript2.pl
Code: (dl )
1
2
3
4
5
6
#!/usr/bin/perl -w
use strict;

my $output;
$output = `./skript1.pl`;
print $output;


Im Moment ist es so, dass natürlich zuerst das skript1.pl ausgeführt wird, alle Ausgaben in $output geschrieben werden und danach alles aufs mal ausgegeben wird.
Was ich jedoch möchte ist, dass sobald skript1.pl etwas ausgibt (bzw. an skript2.pl übergibt) dies von skript2.pl sogleich ausgegeben wird. - und nicht alles aufs mal wie bisher!

Vielen Dank für die Hilfe
esskar
 2006-03-29 00:19
#64141 #64141
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
hi.

lies dir mal perlipc durch.
nepos
 2006-03-29 12:36
#64142 #64142
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
So, wie du es machst, wartet skript2 bis skript1 fertig ist und gibt erst dann die Daten aus. Esskar hat ja schon das richtige Stichwort gegeben.
aedu
 2006-04-04 12:18
#64143 #64143
User since
2005-11-25
4 Artikel
BenutzerIn
[default_avatar]
[quote=esskar,28.03.2006, 22:19]hi.

lies dir mal perlipc durch.[/quote]
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl -w
use strict;
my $i = 0;

while ($i < 10) {
print "bla\n";
sleep(1);
$i++;
}

Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl -w
use strict;

open(STATUS, "./skript1.pl 2>&1 |");

while (<STATUS>) {
print;
}
close STATUS;


Ich habe mich ein bisschen in perlipc eingelesen und das Skript2 danach angepasst. Jetzt ist es aber immer noch so das Skript2 wartet bis Skript1 fertig ist und danach alles auf einmal ausgibt. - Wie kriege ich nun Skript2 dazu dies Ausgaben von Skript1 sofort auszugeben?
pq
 2006-04-04 12:51
#64144 #64144
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
skript1.pl: $| = 1;
siehe perlvar
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
nepos
 2006-04-04 12:51
#64145 #64145
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Liegts vielleicht daran, dass das Skript1 seine Ausgaben puffert?
Dubu
 2006-04-04 12:55
#64146 #64146
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Setze in Skript 1 vor der Schleife
Code: (dl )
$| = 1;

Dann klappt es.


Etwas zum Hintergrund:

Dass die Variable $| das Puffern der Ausgabe steuert, dürfte den meisten klar sein. Unklar ist aber vielleicht, warum obiges Skript1 auf der Kommandozeile auch ohne Änderungen an $| schön jede Sekunde eine Zeile ausgibt, das aber nicht mehr klappt, wenn es von Skript2 aufgerufen wird!
Die Std-Lib versucht hier besonders schlau zu sein: Wenn eine Ausgabe nicht auf STDERR erfolgt und das Ziel ein Terminal  ist, dann wird die Ausgabe zeilenweise gepuffert. Wenn das Ziel aber eine Datei oder Pipe ist, dann wird blockweise gepuffert.

Auch ohne das zweite Skript kann man den Unterschied leicht überprüfen. Man rufe das unveränderte Skript 1 einmal direkt auf:
Code: (dl )
$ ./skript1.pl

und dann zum Vergleich durch more gepipet:
Code: (dl )
$ ./skript1.pl | more

Beim zweiten Aufruf erscheinen auch erst alle zehn Zeilen zum Schluss.

Unter C ist es übrigens nicht viel anders als in Perl: Wenn man auch in einer Pipe jede Zeile sofort sehen möchte, sollte man beizeiten ein fflush() aufrufen. (Oder mit dem Flag O_DIRECT öffnen, was aber langsamer ist, weil dann nach jeder Ein-/Ausgabe geflusht wird.)
aedu
 2006-04-04 13:27
#64147 #64147
User since
2005-11-25
4 Artikel
BenutzerIn
[default_avatar]
[quote=Dubu,04.04.2006, 10:55]Setze in Skript 1 vor der Schleife
Code: (dl )
$| = 1;
[/quote]
Merci Dubu, das war genau das was mir noch fehlte :-)
<< >> 8 Einträge, 1 Seite



View all threads created 2006-03-28 23:15.