pty --- Tiện ích thiết bị đầu cuối giả¶
Source code: Lib/pty.py
Mô-đun pty xác định các hoạt động để xử lý khái niệm thiết bị đầu cuối giả: bắt đầu một quy trình khác và có thể ghi và đọc từ thiết bị đầu cuối điều khiển của nó theo chương trình.
sẵn có: Unix.
Xử lý thiết bị đầu cuối giả phụ thuộc nhiều vào nền tảng. Mã này chủ yếu được thử nghiệm trên Linux, FreeBSD và macOS (nó được cho là hoạt động trên các nền tảng POSIX khác nhưng chưa được kiểm tra kỹ lưỡng).
Mô-đun pty xác định các chức năng sau:
- pty.fork()¶
Cái nĩa. Kết nối thiết bị đầu cuối điều khiển của trẻ với thiết bị đầu cuối giả. Giá trị trả về là
(pid, fd). Lưu ý rằng đứa trẻ nhận được pid 0 và fd là invalid. Giá trị trả về của phần tử cha là pid của phần tử con và fd là bộ mô tả tệp được kết nối với thiết bị đầu cuối điều khiển của phần tử con (và cả với đầu vào và đầu ra tiêu chuẩn của phần tử con).Cảnh báo
Trên macOS, việc sử dụng chức năng này không an toàn khi kết hợp với việc sử dụng API hệ thống cấp cao hơn và bao gồm cả việc sử dụng
urllib.request.
- pty.openpty()¶
Mở một cặp thiết bị đầu cuối giả mới, sử dụng
os.openpty()nếu có thể hoặc mã mô phỏng cho các hệ thống Unix chung. Trả về một cặp mô tả tệp(master, slave), tương ứng cho phần chính và phần phụ.
- pty.spawn(argv[, master_read[, stdin_read]])¶
Tạo ra một quy trình và kết nối thiết bị đầu cuối điều khiển của nó với io tiêu chuẩn của quy trình hiện tại. Điều này thường được sử dụng để gây trở ngại cho các chương trình đòi hỏi phải đọc từ thiết bị đầu cuối điều khiển. Người ta hy vọng rằng quá trình sinh ra đằng sau pty cuối cùng sẽ chấm dứt và khi đó spawn sẽ quay trở lại.
Một vòng lặp sao chép STDIN của tiến trình hiện tại tới tiến trình con và dữ liệu nhận được từ tiến trình con tới STDOUT của tiến trình hiện tại. Nó không được báo hiệu cho trẻ nếu STDIN của tiến trình hiện tại đóng lại.
Các hàm master_read và stdin_read được truyền một bộ mô tả tệp mà chúng sẽ đọc từ đó và chúng phải luôn trả về một chuỗi byte. Để buộc sinh sản quay trở lại trước khi tiến trình con thoát ra, một mảng byte trống phải được trả về tín hiệu cuối tệp.
Việc triển khai mặc định cho cả hai hàm sẽ đọc và trả về tối đa 1024 byte mỗi lần hàm được gọi. Lệnh gọi lại master_read được chuyển qua bộ mô tả tệp chính của pseudoterminal để đọc đầu ra từ quy trình con và stdin_read được chuyển qua bộ mô tả tệp 0, để đọc từ đầu vào tiêu chuẩn của quy trình cha.
Việc trả về một chuỗi byte trống từ một trong hai lệnh gọi lại được hiểu là điều kiện cuối tệp (EOF) và lệnh gọi lại đó sẽ không được gọi sau đó. Nếu stdin_read báo hiệu EOF thì thiết bị đầu cuối điều khiển không thể giao tiếp với tiến trình cha HOẶC tiến trình con nữa. Trừ khi tiến trình con thoát ra mà không có bất kỳ đầu vào nào, spawn sẽ lặp lại mãi mãi. Nếu master_read báo hiệu EOF thì kết quả hành vi tương tự (ít nhất là trên linux).
Trả về giá trị trạng thái thoát từ
os.waitpid()trên tiến trình con.os.waitstatus_to_exitcode()có thể được sử dụng để chuyển trạng thái thoát thành mã thoát.Tăng một auditing event
pty.spawnvới đối sốargv.Thay đổi trong phiên bản 3.4:
spawn()hiện trả về giá trị trạng thái từos.waitpid()trên tiến trình con.
Ví dụ¶
Chương trình sau đây hoạt động giống như lệnh Unix script(1), sử dụng thiết bị đầu cuối giả để ghi lại tất cả đầu vào và đầu ra của phiên cuối trong một "bản đánh máy".
nhập khẩu argparse
hệ điều hành nhập khẩu
nhập khẩu pty
hệ thống nhập khẩu
thời gian nhập khẩu
trình phân tích cú pháp = 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')
tùy chọn = trình phân tích cú pháp.parse_args()
shell = sys.executable nếu options.use_python khác os.environ.get('SHELL', 'sh')
tên tệp = tùy chọn.tên tệp
mode = 'ab' if options.append khác 'wb'
với open(filename, mode) dưới dạng tập lệnh:
đọc chắc chắn (fd):
dữ liệu = os.read(fd, 1024)
script.write(dữ liệu)
trả về dữ liệu
print('Script đã bắt đầu, file is', tên file)
script.write(('Script bắt đầu vào %s\n' % time.asctime()).encode())
pty.spawn(vỏ, đọc)
script.write(('Tập lệnh được thực hiện vào %s\n' % time.asctime()).encode())
print('Kịch bản đã hoàn tất, tệp là', tên tệp)