STDIN einlesen, wenn belegt?

Hallo allerseits,

wie verarbeite ich am geschicktesten Pipe-Input in Perl?

Situation aus Shell in der Art:

echo "Eingabewert" | myScript1 -Params | myScript2 -Params2

Momentan mache ich etwas in dieser Art:

while ( )
{ my $stdinVal=$\_; }

Crux: wenn der STDIN leer ist, wartet das System auf Eingabe.
Wichtig wäre mir, den STDIN nur abzufragen, wenn er belegt ist und sonst eine Fehlermeldung zu croaken.

Wie kriegt man sowas hin?
Danke,
Mike

Hallo,

Crux: wenn der STDIN leer ist, wartet das System auf Eingabe.
Wichtig wäre mir, den STDIN nur abzufragen, wenn er belegt ist
und sonst eine Fehlermeldung zu croaken.

also erstmal kannst du

if (-p STDIN){

abfragen, ob das Programm mit einer Pipe gestartet wurde.

Dann könntest du dich von der Perlfaq inspirieren lassen:

**How do I open a file without blocking?**

 If you're lucky enough to be using a system that supports non-blocking
 reads (most Unixish systems do), you need only to use the O\_NDELAY or
 O\_NONBLOCK flag from the Fcntl module in conjunction with sysopen():

 use Fcntl;
 sysopen(FH, "/foo/somefile", O\_WRONLY|O\_NDELAY|O\_CREAT, 0644)
 or die "can't open /foo/somefile: $!":

Aber für was brauchst du das denn? Wenn du eine Pipe der Form
foo | bar | baz hast, dann werden die Programme bar und baz quasi gleichzeitig mit foo gestartet, d.h. STDIN ist immer am Anfang leer. Also musst du dich fragen, ob das so geht wie du das willst.

Grüße,
Moritz

Hallo, Moritz.

also erstmal kannst du

if (-p STDIN){

abfragen, ob das Programm mit einer Pipe gestartet wurde.

Das hilft mir zumindest schonmal, bei Fehlbenutzung zu croaken und ist ein wichtiger Schritt.

Dann könntest du dich von der Perlfaq inspirieren lassen:

How do I open a file without blocking?

Wunderbar, auch das kann helfen.

Aber für was brauchst du das denn? Wenn du eine Pipe der Form foo | bar | baz hast, dann werden die Programme bar und baz quasi gleichzeitig mit foo gestartet, d.h. STDIN ist immer am Anfang leer.

Im Prinzip hat es mit Schnittstellen zu tun.

Aufgrund der (sagen wir fragwürdigen) Gestaltung des Systems kann ich nicht sicher sein, ob ich schon Daten vom STDIN annehmen muss:

(vorgelagerte Module) | (mein perl) | (nachgelagerte Module)

Wenn vorgelagerte Module nichts ausgeben, aber keinen Fehler melden, muss ich das erkennen können und entsprechend weitermachen.

Und die außenstehenden Module sind meistens nicht perl.

Gruss,
Mike

Hallo,

Aber für was brauchst du das denn? Wenn du eine Pipe der Form foo | bar | baz hast, dann werden die Programme bar und baz quasi gleichzeitig mit foo gestartet, d.h. STDIN ist immer am Anfang leer.

Im Prinzip hat es mit Schnittstellen zu tun.

Aufgrund der (sagen wir fragwürdigen) Gestaltung des Systems
kann ich nicht sicher sein, ob ich schon Daten vom STDIN
annehmen muss:

(vorgelagerte Module) | (mein perl) | (nachgelagerte
Module)

Wenn vorgelagerte Module nichts ausgeben, aber keinen Fehler
melden, muss ich das erkennen können und entsprechend
weitermachen.

Und die außenstehenden Module sind meistens nicht perl.

D.h. die vorgelagerten Module geben nichts aus, aber beenden sich nicht? wie unschön :wink:

Was du machen kannst, ist nach jedem lesen von STDIN eine timestamp-Veriable setzen, und vor dem ersten lesen einen zweiten Thread starten, der alle 10 Sekunden die()ed/croak()ed wenn die timestamp nicht aktualisiert wurde.

Grüße,
Moritz