Comment puis-je vérifier (coup d'oeil) STDIN pour les données en Perl sans passepoilées utiliser select?

StackOverflow https://stackoverflow.com/questions/518992

Question

Je suis en train de gérer la possibilité qu'aucun argument et aucune donnée est canalisée transmis à un script Perl. Je suppose que s'il n'y a aucun argument alors entrée est canalisée via STDIN. Toutefois, si l'utilisateur fournit aucun argument et ne rien pipe pour le script, il va essayer d'obtenir l'entrée du clavier. Mon objectif est de fournir un message d'erreur.

Malheureusement, n'est pas portable select() à certains systèmes non-POSIX. Y at-il une autre façon de le faire avec une portabilité maximale?

Était-ce utile?

La solution

Perl est livré avec l'opérateur de fichiers -t test, qui vous indique si un descripteur de fichier particulier est ouvert à un ATS. Donc, vous devriez être en mesure de le faire:

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.
}

Un test rapide révèle ce fonctionne bien sur Windows avec Perl 5.10.0, et Linux avec Perl 5.8.8, il devrait donc être portable dans les environnements Perl les plus courants.

Comme d'autres l'ont mentionné, ne serait pas select un choix fiable car il peut y avoir des moments où vous êtes en train de lire un processus, mais ce processus n'a pas commencé à écrire encore.

Cordialement,

Paul

Autres conseils

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

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

Notez que sélectionner ne serait pas beaucoup d'aide de toute façon, car il produirait des résultats faux Si l'information était canalisée pas encore prêt. Exemple:

seq 100000|grep 99999|perl -we'$rin="";vec($rin,fileno(STDIN),1)=1;print 0+select($rin,"","",.01)'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top