2009-02-06 9 views
9

J'essaie de gérer la possibilité qu'aucun argument et aucune donnée transmise ne soient passés à un script Perl. Je suppose que s'il n'y a aucun argument alors l'entrée est canalisée via STDIN. Cependant, si l'utilisateur ne fournit aucun argument et ne canalise rien au script, il essayera d'obtenir une entrée au clavier. Mon objectif est de fournir un message d'erreur à la place.Comment puis-je vérifier (aperçu) STDIN pour les données canalisées en Perl sans utiliser select?

Malheureusement, select() n'est pas portable sur certains systèmes non-POSIX. Existe-t-il un autre moyen de le faire avec une portabilité maximale?

Répondre

19

Perl est livré avec l'opérateur de test de fichier -t, 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 beau travail sur Windows avec Perl 5.10.0, et Linux avec Perl 5.8.8, il devrait donc être portable sur le plus commun Perl environnements.

Comme d'autres l'ont mentionné, select ne serait pas un choix fiable car il se peut que vous lisiez un processus, mais ce processus n'a pas encore commencé à écrire.

Tous les meilleurs,

Paul

+0

Confirmé pour fonctionner sur Mac OS X. +5 si je le pouvais, mais je ne peux pas, donc +1. –

5
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'info é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)' 
+0

Ce n'est pas mieux que 'select()', vous utilisez trop POSIX. L'OP a spécifiquement dit: * Malheureusement, select() n'est pas portable pour certains systèmes non-POSIX. * – nyuszika7h

+0

J'explique ce qui serait mieux que de choisir où la portabilité non-POSIX n'est pas un problème. – ysth