2009-02-06 9 views
9

Ich versuche, die Möglichkeit zu behandeln, dass keine Argumente und keine piped Daten an ein Perl-Skript übergeben werden. Ich gehe davon aus, dass wenn keine Argumente vorhanden sind, die Eingabe über STDIN weitergeleitet wird. Wenn der Benutzer jedoch keine Argumente bereitstellt und nichts an das Skript übergibt, wird versucht, Tastatureingaben zu erhalten. Mein Ziel ist es stattdessen eine Fehlermeldung zu liefern.Wie kann ich STDIN für piped Daten in Perl überprüfen (ohne peek) wählen?

Leider ist select() nicht auf einige Nicht-POSIX-Systeme portierbar. Gibt es eine andere Möglichkeit, dies mit maximaler Portabilität zu tun?

Antwort

19

Perl mit dem -t Datei-Testfahrer kommt, die Ihnen sagt, ob eine bestimmte Dateikennung an ein TTY offen ist. Also, sollten Sie in der Lage sein, dies zu tun:

if (-t STDIN and not @ARGV) { 
    # We're talking to a terminal, but have no command line arguments. 
    # Complain loudly. 
} 
else { 
    # We're either reading from a file or pipe, or we have arguments in 
    # @ARGV to process. 
} 

Ein kurzer Test zeigt diese Arbeit gut auf Windows mit Perl 5.10.0 und Linux mit Perl 5.8.8, so dass es über den gängigste Perl tragbar sein sollte Umgebungen.

Wie andere bereits erwähnt haben, wäre select keine zuverlässige Wahl, da es manchmal vorkommen kann, dass Sie aus einem Prozess lesen, aber dieser Prozess hat noch nicht begonnen zu schreiben.

Alles Gute,

Paul

+0

Bestätigt, um unter Mac OS X zu arbeiten. +5 wenn ich könnte, aber ich kann nicht, also +1. –

5
use POSIX 'isatty'; 
if (! @ARGV && isatty(*STDIN)) { 
    die "usage: ..."; 
} 

See: http://www.opengroup.org/onlinepubs/009695399/functions/isatty.html

Beachten Sie, dass wählen würde nicht viel helfen sowieso, da es falsche Ergebnisse produzieren würde, wenn die verrohrt Informationen noch nicht fertig war. Beispiel:

seq 100000|grep 99999|perl -we'$rin="";vec($rin,fileno(STDIN),1)=1;print 0+select($rin,"","",.01)' 
+0

Dies ist nicht besser als 'select()', sind Sie POSIX zu verwenden. Das OP hat speziell gesagt: * Leider ist select() nicht auf einige Nicht-POSIX-Systeme übertragbar. * – nyuszika7h

+0

Ich erkläre, was besser wäre, als auszuwählen, wo Nicht-POSIX-Portabilität keine Rolle spielt. – ysth