2010-09-21 50 views
40

En Python, ¿cómo se comprueba si sys.stdin tiene datos o no?¿Cómo verifico si stdin tiene algunos datos?

Encontré que os.isatty(0) no solo puede verificar si stdin está conectado a un dispositivo TTY, sino también si hay datos disponibles.

Pero si alguien usa un código como

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

y después de eso utiliza os.isatty(0), todavía devuelve True. ¿Qué debo hacer para verificar si stdin tiene datos?

+3

¿Qué es exactamente lo que quiere lograr? – shahjapan

+0

Eso está sucediendo porque 'os.isatty (0)' verifica si el archivo asociado al descriptor de archivo (fd) 0 es un TTY. Cuando cambia la variable 'sys.stdin', no está cambiando el archivo asociado a fd0. fd0 todavía apunta al stdin original (que es un TTY en su caso). –

+2

Compruebe [esta respuesta] (http://stackoverflow.com/questions/3731681/capturing-user-input-at-arbitrary-times-in-python/3732001#3732001). ¿Pertenece a tu pregunta? –

Respuesta

49

En los sistemas Unix que puede hacer lo siguiente:

import sys 
import select 

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

En Windows el módulo de selección sólo se puede utilizar con los zócalos, aunque por lo que había necesidad de utilizar un mecanismo alternativo.

+0

esto es exactamente lo que necesito, gracias – mlzboy

+0

lamento tener que eliminar el aceptar, porque uso sys.stdin = cStringIO .StringIO ("ddd") redirige el archivo stdin a un archivo simulado, pero no tenía el método fileno, uso tu código, lo elevará si no lo seleccionas.selecciona ([sys.stdin], [], [], 0.0) [0]: TypeError: el argumento debe ser un int, o tener un método fileno(). – mlzboy

+0

@mlzboy: solo los archivos "reales", abiertos por el sistema operativo tienen un número de descriptor de archivo (por cierto, los sockets Unix o los pipes también son archivos). 'select' que llama a la función de selección del sistema operativo puede funcionar solo con esos archivos.'StringIO' es un archivo virtual conocido solo por el intérprete de Python, por lo tanto, no tiene un descriptor de archivo y no puede usar' select' en él. –

1

Dependiendo del objetivo aquí:

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

también pueden ser útiles.

+0

AFAIK, la entrada de archivo tiene una desventaja que limita los argumentos debe tener el nombre del archivo, pero mis argumentos pueden ser algunos comandos de control, – mlzboy

+0

¡Bastante justo! Estaba tratando de manejar el modismo común de "hacer algo con un montón de líneas, posiblemente desde stdin" :) –

39

He estado usando

if not sys.stdin.isatty() 

He aquí un ejemplo:

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() devuelve falso si hay algo en la entrada estándar.

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

¡Gracias! Esto es mucho más fácil que usar 'select'. –

+0

Gracias. Eso resolvió mi: echo 'maybe pipe' | stdin.py + maybe_args en Linux. ¿La solución de melancholynaturegirl funciona en Windows? –

+0

por lo que parece ... C: \ Users \ naturegirl \ Desktop> C: \ python27 \ python.exe isatty.py es sys.stdin.isatty C: \ Users \ naturegirl \ Desktop> C: \ Users \ naturegirl \ Desktop> echo "foo" | C: \ Python27 \ python.exe isatty.py no sys.stdin.isatty – liang

1

Como han mencionado otros, no existe una forma infalible de hacerlo, porque UNIX no lo permite. Espere siempre el stdin, aunque no haya nada (eso es lo que grep etc.), o solicite al usuario un argumento -.

+1

Entonces, ¿está respondiendo una pregunta refiriéndose a la misma pregunta? ¿WTF? – ForceBru

+0

@ForceBru Esto es realmente muy confuso, jaja. Parecería que otra pregunta se fusionó aquí. He editado –

+0

¿Cuál sería el proceso? Espere el stdin y lea hasta un EOF, luego procese los datos. Es decir, ¿cómo grep et al. ¿Saber cuándo procesar los datos y cuándo dejarlos? – Matt

Cuestiones relacionadas