35.8. pty --- 擬似端末ユーティリティ

ソースコード: Lib/pty.py


pty モジュールは擬似端末(他のプロセスを実行してその制御をしている端末をプログラムで読み書きする)を制御する操作を定義しています。

擬似端末の制御はプラットフォームに強く依存するので、Linux用のコードしか存在していません。(Linux用のコードは他のプラットフォームでも動作するように作られていますがテストされていません。)

pty モジュールでは以下の関数を定義しています:

pty.fork()

forkします。子プロセスの制御端末を擬似端末に接続します。返り値は (pid, fd) です。子プロセスは pid として0、fd として invalid をそれぞれ受けとります。親プロセスは pid として子プロセスのPID、fd として子プロセスの制御端末 (子プロセスの標準入出力に接続されている)のファイル記述子を受けとります。

pty.openpty()

新しい擬似端末のペアを開きます。利用できるなら os.openpty() を使い、利用できなければ一般的なUnixシステム用のエミュレーションコードを使います。マスター、スレーブそれぞれのためのファイル記述子、 (master, slave) のタプルを返します。

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

プロセスを生成して制御端末を現在のプロセスの標準入出力に接続します。これは制御端末を読もうとするプログラムをごまかすために利用されます。

master_readstdin_read にはファイル記述子から読み込む関数を指定してください。デフォルトでは呼ばれるたびに1024バイトずつ読み込もうとします。

バージョン 3.4 で変更: spawn()os.waitpid() が返す子プロセスのステータス値を返すようになりました。

35.8.1. 使用例

下記のプログラムは Unix コマンド script(1) のように動作します。疑似端末を使用して、端末セッションのすべての入出力を "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)