2017-09-27 15 views
1

J'écris un outil de ligne de commande (appelons-le interactive_rm), qui est censé lire la ligne de chemins de fichiers en ligne à partir de STDIN afin qu'il puisse être utilisé avec des tuyaux Unix comme dans l'exemple suivant:Obtenir l'entrée de l'utilisateur en lisant STDIN à partir d'un tuyau?

$ find . | interactive_rm 

Je suis en train de lire chaque chemin de STDIN comme ceci:

def _parse_stdin(): 
    for line in sys.stdin: 
     yield prepare_line(line) 

maintenant, le problème ... Avant l'outil supprime un chemin, il doit demander confirmation à l'utilisateur. Pour ce faire, j'utiliser input() comme ceci:

for path in _parse_stdin(): 
    print('Do you want to delete this path: [y/n]\n' + path) 
    answer = input() 
    if answer == 'y': 
     delete(path) 

Mais cela ne fonctionne pas, parce que STDIN est déjà occupée par le tuyau, de sorte que la fonction input() est ignorée ou je finis avec un « EOFError: EOF lors de la lecture d'une ligne ".

Est-ce que quelqu'un connaît une solution à cela?

Répondre

1

Lorsque stdin est redirigée, il faut rouvrir le terminal pour pouvoir lire de lui, par exemple:

from __future__ import print_function 

import os 

def main(): 
    tty = os.open("/dev/tty", os.O_RDONLY) 
    while True: 
     r = os.read(tty, 1024) 
     if not r: # Wait for Ctrl-D. 
      break 
     print("----", r) 

if __name__ == "__main__": 
    main() 

Et l'exécuter comme suit pour le tester:

python t.py < /dev/null 

Remarque que le terminal peut être indisponible. Par exemple, si la commande est exécutée via une session ssh sans attribuer de terminal comme ssh -T ... command.