2015-08-06 1 views
11

Je suis en train d'exécuter un script pexpect de base:pexpect et PyCharm - ioctl pour le dispositif inapproprié

import pexpect 
ftp_process = pexpect.spawn('ftp') 
ftp_process.interact() 

Lorsque le code est exécuté directement à partir d'un terminal, le code fonctionne comme prévu. Si je lance le code à l'aide run/debug je reçois l'erreur suivante de PyCharm:

Traceback (most recent call last): 
    File "/path/to/code/test.py", line 3, in <module> 
    ftp_process.interact() 
    File "/usr/local/lib/python3.4/site-packages/pexpect/__init__.py", line 1645, in interact 
    mode = tty.tcgetattr(self.STDIN_FILENO) 
termios.error: (25, 'Inappropriate ioctl for device') 

Il semble que la façon dont pexpect interagit avec l'exécution/la fenêtre de débogage de PyCharm ne fonctionne pas par défaut. Y at-il un moyen de remédier à cela avec un paramètre PyCharm spécifique? Sinon, existe-t-il un autre moyen de contourner ce problème?

EDIT

Le code ci-dessus est simplement un exemple raccourci qui se traduit par le problème. Les autres capacités de pexpect (telles que expect(), sendline(), etc.) sont encore souhaitées.

+0

PyCharm doit fournir un pseudo-tty (pty) au lieu d'un canal, par exemple, le code s'exécute correctement depuis Emacs. Vous pouvez essayer 'pty.spawn ('ftp')' – jfs

+0

@ J.F.Sebastian, c'est une réponse, ça marche. –

+0

@ J.F.Sebastian: pty fonctionne pour ce cas, mais ce n'est vraiment qu'un exemple simplifié. J'ai toujours besoin du pouvoir de pexpect. Je ne vois pas comment faire pour que PyCharm fournisse un pseudo-tty, mais peut-être quelqu'un qui répondra à cette question saura-t-il. – golmschenk

Répondre

-1

Il semblerait que pexpect soit installé correctement sur votre installation Python par défaut, il se peut qu'une autre instance de python ne possède pas de bibliothèque pexpect installée ou installée correctement. Dans vos paramètres PyCharm, essayez de le positionner sur votre installation Python par défaut/correcte.

+0

Merci pour la réponse, mais cela ne semble pas se produire en raison d'un problème avec l'installation de Pexpect ou de l'interpréteur utilisé par PyCharm. Il semble être un problème avec la façon dont "terminal" de l'exécution/débogage de PyCharm communique avec Pexpect. – golmschenk

0

Essayez quelque chose qui peut allouer Pseudo TTYs. Cela devrait tromper ftp en pensant qu'il a un TTY (qui est quelque chose qui est donné lorsque vous exécutez Python REPL à partir du terminal). Exemple:

pexpect.pty.spawn('ftp') 

Vous pouvez également essayer ptyprocess bien que je ne peux pas garantir qu'il est correct/être dans un état de fonctionnement.

+0

Connaissez-vous de la documentation pour la fonction 'pty_spawn'? Je ne vois que le fichier de ce nom qui contient la fonction 'spawn' que j'utilise déjà et en essayant d'appeler cette fonction, un objet 'module' n'a pas d'erreur d'attribut. – golmschenk

+0

Désolé, cela devrait être 'pexpect.pty.spawn'. – knight

+0

Cela fait maintenant apparaître le processus, mais d'autres commandes pexpect (expect, sendline, etc) ne peuvent pas être utilisées par la suite car il semble que le programme attende l'appel pty. Des réflexions sur la façon de permettre cela à travers cette approche? – golmschenk

2

Remarque: Ceci est seulement une solution de contournement, mais cela fonctionne.

Si le script est appelé à partir d'un pseudo-terminal en utilisant un script séparé, les résultats souhaités peuvent être obtenus. Par exemple, en utilisant pty.spawn("python my_script.py".split()) où my_script.py est celui utilisant pexpect.

J'ai trouvé raisonnable d'avoir un seul script qui tente les appels pexpect initialement dans un try/except et en attrapant l'erreur, faire le script se rappeler dans un pseudo-tty. Le mérite revient à J.F. Sebastian dans les commentaires de la question initiale.