2009-12-12 10 views
5

Sto scrivendo sul mio processo Python dalla riga di comando su unix. Voglio inviare EOF (o in qualche modo svuotare il buffer stdin, quindi Python può leggere il mio input.)Come inviare EOF a Python sys.stdin dalla riga di comando? CTRL-D non funziona

Se premo CTRL-C, ottengo un KeyboardError.

Se colpisco CTRL-D, il programma si ferma proprio.

Come faccio a scaricare il buffer stdin?

+2

Il modo in cui la maggior parte dei terminali funziona, non appena si preme Invio, l'input viene inviato a Python. –

+0

Se vuoi cambiare il modo in cui funziona, Python deve cambiare le impostazioni del terminale, che è magia nera ... vedi il modulo 'termios', forse? http://docs.python.org/library/termios.html –

risposta

1

Se si utilizza 'per l in sys.stdin', si è tamponato.

È possibile utilizzare:

while 1: 
    l = sys.stdin.readline() 
+0

È bufferizzato comunque. Non c'è differenza tra i due. –

+0

In realtà, quanto sopra ha funzionato per me. Penso di aver letto sulla mailing list che "per l in sys.stdin" ha un buffer interno extra, mentre sys.stdin.readline() no. –

+2

@JasonOrendorff: in realtà c'è una differenza su Python 2 a causa di [bug del buffer read-ahead] (http://bugs.python.org/issue3907). Si potrebbe usare 'per line in iter (sys.stdin.readline, ''):' per risolvere il problema. Prova a eseguire 'cat | python2 -u -c "" "e digita qualche input. La variante 'readline()' fa in modo che le righe siano immediatamente disponibili. – jfs

11

Control-D non dovrebbe rendere il vostro programma "solo stop" - dovrebbe chiudere standard input, e se i vostri programma si occupa di che correttamente, può benissimo continuare se ha bisogno di!

Ad esempio, dato il seguente st.py:

import sys 

def main(): 
    inwas = [] 
    for line in sys.stdin: 
    inwas.append(line) 
    print "%d lines" % len(inwas), 
    print "initials:", ''.join(x[0] for x in inwas) 

if __name__ == '__main__': 
    main() 

abbiamo potuto vedere qualcosa di simile

$ python st.py 
nel mezzo del cammin di nostra vita 
mi ritrovai per una selva oscura 
che la diritta via era smarrita 
3 lines initials: nmc 
$ 

se il controllo-D viene colpito subito dopo l'entrare nella terza riga - il programma si rende conto che l'input standard è eseguito e esegue la necessaria post-elaborazione, tutto pulito e corretto.

Se il tuo programma termina prematuramente su control-D, deve essere codificato male - che ne dici di modificare la tua domanda per aggiungere il più piccolo programma "misbehaving" che puoi immaginare, così possiamo mostrarti esattamente come stai andando sbagliato?

2

Penso di sapere cosa sta succedendo. Stai colpendo ctrl-D senza colpire enter. Se vuoi inviare una riga al programma, premi invio. Se si colpisce ctrl-D senza colpire enter, è possibile premere nuovamente ctrl-D e il programma dovrebbe visualizzare la riga. In questo caso (due in successione ctrl-D), il programma non vedrà una nuova riga alla fine della riga.

Per esempio, diciamo che ho uno script Python a.py:

import sys 

for line in sys.stdin: 
    sys.stdout.write('%s' % line) 

E io eseguirlo:

$ python a.py 

e quindi immettere il seguente:

line 1 
line 2<ctrl-D><ctrl-D> 

il programma stamperà:

line 1 
line 2$ 

$ è il prompt della shell. Ecco una sessione completa con l'input sopra riportato:

$ python a.py
linea 1
linea 2 line1
linea 2 $

(Bold Visualizza Valori. Romano caso del programma è per mostrare ciò che ho scritto, sans le due ctrl-D s)

Se questo non è ciò che sta accadendo, devi dirci di più su quello che stai facendo.

1
try: 
    # You might be inside the while-loop 
    foo = raw_input('Spam: ') # Or whatever... 
except EOFError: 
    print 'And now for something completely different.' 
    sys.exit() 
Problemi correlati