2010-09-21 7 views
40

En python, comment vérifier si sys.stdin a des données ou pas?Comment vérifier si stdin a des données?

J'ai trouvé que os.isatty(0) peut non seulement vérifier si stdin est connecté à un appareil TTY, mais aussi s'il y a des données disponibles.

Mais si quelqu'un utilise un code tel que

sys.stdin = cStringIO.StringIO("ddd") 

et après qui utilise os.isatty(0), il retourne toujours vrai. Que dois-je faire pour vérifier si stdin a des données?

+3

exactement ce que vous voulez réaliser? – shahjapan

+0

Cela se produit parce que 'os.isatty (0)' vérifie si le fichier associé au descripteur de fichier (fd) 0 est un TTY. Lorsque vous modifiez la variable 'sys.stdin', vous ne modifiez pas le fichier associé à fd0. fd0 pointe toujours sur le stdin d'origine (qui est un TTY dans votre cas). –

+2

Cochez cette réponse (http://stackoverflow.com/questions/3731681/capturing-user-input-at-arbitrary-times-in-python/3732001#3732001). Cela concerne-t-il votre question? –

Répondre

49

Sur les systèmes Unix, vous pouvez effectuer les opérations suivantes:

import sys 
import select 

if select.select([sys.stdin,],[],[],0.0)[0]: 
    print "Have data!" 
else: 
    print "No data" 

Sous Windows, le module de sélection ne peut être utilisé avec des prises si vous auriez donc besoin d'utiliser un autre mécanisme.

+0

c'est exactement ce dont j'ai besoin, merci – mlzboy

+0

je suis désolé je dois enlever l'accepter, parce que j'utilise sys.stdin = cStringIO .StringIO ("ddd") redirige le fichier stdin vers un fichier fictif, mais il n'a pas de méthode fileno, il utilise le code qu'il va lever sinon select.select ([sys.stdin], [], [], 0.0) [0]: TypeError: l'argument doit être un int, ou avoir une méthode fileno(). – mlzboy

+0

@mlzboy: seuls les fichiers "réels", ouverts par le système d'exploitation, ont un numéro de descripteur de fichier (btw sur les sockets Unix ou les tubes sont aussi des fichiers). 'select' qui appelle la fonction select du système d'exploitation ne peut fonctionner qu'avec ces fichiers.StringIO est un fichier virtuel connu uniquement de l'interpréteur Python, par conséquent il n'a pas de descripteur de fichier et vous ne pouvez pas utiliser 'select'. –

1

Selon l'objectif ici:

import fileinput 
for line in fileinput.input(): 
    do_something(line) 

peut également être utile.

+0

AFAIK, l'entrée de fichier a un inconvénient ce qui limite les arguments doit être le nom de fichier, mais mes arguments peuvent être une commande de contrôle, – mlzboy

+0

Assez juste! J'essayais de gérer l'idiome commun de "faire quelque chose à un tas de lignes, peut-être de stdin" :) –

39

J'utilise

if not sys.stdin.isatty() 

Voici un exemple:

4 import sys 
5 
6 def main(): 
7  if not sys.stdin.isatty(): 
8   print "not sys.stdin.isatty" 
9  else: 
10   print "is sys.stdin.isatty" 

>echo "asdf" | stdin.py 
not sys.stdin.isatty 

sys.stdin.isatty() retourne false s'il y a quelque chose dans stdin.

isatty(...) 
    isatty() -> true or false. True if the file is connected to a tty device. 
+3

Merci! C'est tellement plus facile que d'utiliser 'select'. –

+0

Merci. Cela a résolu mon: echo 'peut-être pipe' | stdin.py + maybe_args sur linux. Est-ce que la solution de melancholynaturegirl fonctionne sur Windows? –

+0

il semble ... C: \ Users \ naturegirl \ Desktop> C: \ Python27 \ python.exe isatty.py est sys.stdin.isatty C: \ Users \ naturegirl \ Desktop> C: \ Utilisateurs \ naturegirl \ Desktop> echo "foo" | C: \ Python27 \ python.exe isatty.py pas sys.stdin.isatty – liang

1

Comme mentionné par d'autres, il n'y a pas de moyen infaillible de le faire, car UNIX ne le permet pas. Toujours attendre stdin, même s'il n'y a rien (c'est ce que font grep etc.), ou demander à l'utilisateur un argument -.

+1

Donc, vous répondez à une question en vous référant à la même question? WTF ?? – ForceBru

+0

@ForceBru C'est en effet très confus, haha. Il semblerait qu'une autre question a été fusionnée ici. J'ai édité. –

+0

Quel serait le processus - attendre stdin et lire jusqu'à un EOF, puis traiter les données? Autrement dit, comment grep et al. savoir quand traiter les données et quand quitter? – Matt

Questions connexes