2010-06-04 3 views
6

Ich habe ein Skript bekam, die Standardeingabe packt:In Perl, wie ermittle ich, ob eine Standardeingabe vorhanden ist?

&process_input 

sub process_input { 
    while(<STDIN>) { 
     $log_data .= $_; 
    } 
} 

Als ich das Skript ausführen:

myscript.pl -param1=a -param2=b 

ich in diesem Unterprogramm stecken. Alles läuft in Ordnung, wenn ich tun:

echo "" | myscript.pl -param1=a -param2=b 

Frage ist, wie kann ich feststellen, ob ich auch einen Standard in Put haben? Ich hätte gedacht, dass while() würde falsch zurückgeben und nicht laufen, aber ich schätze, es ist tatsächlich warten auf Sie, um etwas zu tippen, warum es "festgefahren" ist.

+1

mögliche Duplikate von [Wie kann ich feststellen, ob STDIN mit einem Terminal in Perl verbunden ist?] (Http://stackoverflow.com/questions/528781/how-can-i-tell-if-stdin-is-connected -to-a-terminal-in-perl) – Ether

Antwort

18

Was Sie tun möchten, ist zu überprüfen, woher Ihre STDIN (STanDard INput) kommt: eine andere Anwendung oder ein Terminal. In Ihrem Fall ist dies die zweite Option, die dazu führt, dass eine Leseoperation den Prozess blockiert, bis der Benutzer etwas eingibt. Eine Lösung finden Sie unter How can I tell if STDIN is connected to a terminal in Perl?.

if (-t STDIN) { 
    # input attached to terminal and will probably ask user 
} else { 
    # input from other process 
} 

Es gibt auch IO::Interactive, die besser/zuverlässige Kontrolle tun könnten.

+0

Vielen Dank! Da das Skript auch von einer anderen Anwendung ausgeführt werden kann, könnte ich die Option -t verwenden. – EDJ

2

Die Anweisung <STDIN> kehrt erst zurück, wenn Sie "enter" auf der Konsole drücken. Wenn Sie dies umgehen wollen, glaube ich, dass Sie IO::Handle verwenden können, um STDIN zu wickeln, und $stdin->blocking(0) aufrufen, um non-blocking IO zu aktivieren.

+2

Das Problem blockiert IO nicht, aber dass '' (was äquivalent zu 'readline (* FILEHANDLE)') ist, sucht nach einer Eingabezeile. Es wird nicht zurückkommen, bis ein '\ n' (naja, technisch eine Instanz des Eingabesatztrennzeichens' $/') gefunden wird.Es spielt keine Rolle, ob der Griff blockiert oder nicht. Wenn Sie 'IO :: Handle' verwenden, können Sie einfach seine Methoden für vorhandene globale Handles verwenden:' STDIN-> blocking (0); ' – daotoad

1

Das ist normal. Standardmäßige Verwendung für Unix-Tools ist die Verwendung von STDIN, wenn keine Eingabedatei als Argument angegeben wird. Versuchen Sie cat, less, grep, etc. Es ist bis zu dem Anrufer Eingabe bereitzustellen, wenn nur

tool < /dev/null 

ich dringend davon abraten, versuchen zu bestimmen, ob „Input“, da es Probleme verfügbar ist egal vorstellen, wie Sie erreichen Dies. Vermeiden Sie insbesondere -t, da es problematisch ist, ein Terminal bei Bedarf zu fälschen. Verlassen Sie sich stattdessen auf eine konventionellere Schnittstelle.

Wenn Sie möchten, dass keine Eingabe an Ihr Werkzeug übergeben wird, ist es seltsam, dass Sie STDIN überhaupt verwenden. Man würde normalerweise ein optionales Argument verwenden.

Eine weitere Option wäre, dass der Benutzer Sie anfordert, wenn keine Eingabe erfolgt.

tool --batch 

Um Ihnen bei den Entwurfsproblemen Ihrer Schnittstelle zu helfen, würde es wirklich helfen zu wissen, was Ihr Werkzeug tut.

0

Ihr Programm wird fortgesetzt, wenn der Benutzer Strg + D, das Ende der Datei Zeichen eingibt.