# 35.8. `pty` — Outils de manipulation de pseudo-terminaux

Code source : Lib/pty.py

Le module `pty` expose des fonctions de manipulation de pseudo-terminaux, il permet d’écrire un programme capable de démarrer un autre processus, d’écrire et de lire depuis son terminal.

La gestion de pseudo-terminaux étant très dépendante de la plateforme, ce code ne gère que Linux. (Code supposé fonctionner sur d’autres plateformes, mais sans avoir été testé).

Le module `pty` expose les fonctions suivantes :

`pty.``fork`()

  Fork. Connecte le terminal contrôlé par le fils à un pseudo-terminal. La valeur renvoyée est `(pid, fd)`. Notez que le fils obtient `0` comme pid et un fd non valide. Le parent obtient le pid du fils, et fd un descripteur de fichier connecté à un terminal contrôlé par le fils (et donc à l’entrée et la sortie standard du fils).

`pty.``openpty`()

  Ouvre une nouvelle paire de pseudo-terminaux, en utilisant si possible `os.openpty()`, ou du code émulant la fonctionnalité pour des systèmes Unix génériques. Renvoie une paire de descripteurs de fichier `(master, slave)`, pour le maître et pour l’esclave respectivement.

`pty.``spawn`(argv[, master_read[, stdin_read]])

  Crée un nouveau processus et connecte son terminal aux entrées/sorties standard du processus courant. C’est typiquement utilisé pour duper les programmes insistant sur le fait de lire depuis leur terminal.

  Les fonctions master_read et stdin_read doivent être des fonctions lisant sur un descripteur de fichier. Par défaut elles lisent 1024 octets à chaque fois qu’elles sont appelées.

  Modifié dans la version 3.4: `spawn()` renvoie maintenant la valeur renvoyée par `os.waitpid()` sur le processus fils.

## 35.8.1. Exemple

Le programme suivant se comporte comme la commande Unix script(1), utilisant un pseudo-terminal pour enregistrer toutes les entrées et sorties d’une session dans un fichier typescript.

    import argparse
    import os
    import pty
    import sys
    import time

    parser = argparse.ArgumentParser()
    parser.add_argument('-a', dest='append', action='store_true')
    parser.add_argument('-p', dest='use_python', action='store_true')
    parser.add_argument('filename', nargs='?', default='typescript')
    options = parser.parse_args()

    shell = sys.executable if options.use_python else os.environ.get('SHELL', 'sh')
    filename = options.filename
    mode = 'ab' if options.append else 'wb'

    with open(filename, mode) as script:
        def read(fd):
            data = os.read(fd, 1024)
            script.write(data)
            return data

        print('Script started, file is', filename)
        script.write(('Script started on %s\n' % time.asctime()).encode())

        pty.spawn(shell, read)

        script.write(('Script done on %s\n' % time.asctime()).encode())
        print('Script done, file is', filename)