IFT585 - Q&R - Exécution de programmes interactifs
par Benoit, 2014-05-14

Question

Dans le problème numéro 1, doit-on être capable d’executer des programmes intéractifs comme vim ou python par exemple ?

Réponse

On doit être en mesure de rouler les programmes interactifs qui ne sont pas basés sur la manipulation d’une émulation de terminal. De tels programmes tiennent compte du nombre de lignes et de colonne de votre fenêtre de terminal, et sont en mesure de tracer une interface graphique, ainsi que de positionner le curseur à un endroit arbitraire dans la fenêtre. Vim est un tel programme, et je ne m’attends pas à ce que vous puissiez le rouler avec reshd/resh.

En revanche, Python peut fonctionner interactivement sans émulation de terminal. Lorsque vous démarrez Python en mode interactif, il vérifie si son entrée standard est un terminal. Si c’en est un, Python se dote de quelques fonctionnalités d’édition de la ligne de commande; sinon, Python prend simplement ses commandes de l’entrée standard. Cependant, Python a un comportement légèrement étrange en ceci qu’il imprime des invites: ce sont les caractères >>> qui précèdent une ligne, suggérant la possibilité d’interagir. Comme ces invites ne sont pas suivies d’une fin de ligne, la sortie standard de Python n’est pas “prête à la lecture” avant qu’une commande ne soit envoyée. Cela fait en sorte que vous lirez les caractères de l’invite juste avant les caractères de la réponse à une ligne de commande, sans fin de ligne entre les deux; les réponses seront donc précédées de l’invite, et non les instructions, ce qui je trouve très hilarant. En outre, si le résultat d’une instruction est la valeur spéciale None, cette dernière n’est pas imprimée par défaut. Ainsi, l’exécution d’une fonction qui renvoit None ne causera pas la lecture de l’invite. Vous pouvez donc retarder ainsi la lecture de multiples invites, qui apparaîtront toutes ensemble lors de l’exécution d’une instruction qui renverra un résultat. Voici un exemple d’une session Python exécutée via mon propre resh. Je précède chaque ligne tapée à la main du symbole ->.

-> $ ./resh localhost 9887 python -i
   Python 2.7.5+ (default, Sep 17 2013, 15:31:50)
   [GCC 4.8.1] on linux2
   Type "help", "copyright", "credits" or "license" for more information.
-> 5+6
   >>> 11
-> print 8+9
   >>> 17
-> import struct
-> import socket
-> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
-> s
   >>> >>> >>> >>> <socket._socketobject object at 0x7f57e06a66e0>
-> import sys
-> sys.exit(0)
   >>> >>> $