скрипт Python: pexpect зависает на child.wait ()? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть рабочий скрипт в Linux, который создает ssh-ключи. В macOS он зависает при ожидании ().

import os
import sys

import pexpect


passphrase = os.environ['HOST_CA_KEY_PASSPHRASE']

command = 'ssh-keygen'
child = pexpect.spawn(command, args=sys.argv[1:])
child.expect('Enter passphrase:')
child.sendline(passphrase)
child.wait()

1 Ответ

0 голосов
/ 07 ноября 2019

Наконец-то я нашел проблему. Кажется, что двоичный файл ssh-keygen немного отличается, и он выводит некоторые вещи после.

, потому что wait () является блокирующим вызовом.

Это не будет считывать данные от дочернего элемента,поэтому это навсегда заблокирует , если дочерний элемент имеет непрочитанный вывод и завершил работу. Другими словами, дочерний элемент может печатать выходные данные, которые затем называются exit (), но технически дочерний элемент все еще жив, пока его выходные данные не будут считаны родительским элементом.

.wait () документы здесь

для решения этой проблемы read_nonblocking считывает символы максимального размера из дочернего приложения. Если есть байты, доступные для немедленного чтения, все эти байты будут считаны (вплоть до размера буфера).

.read_nonblocking () документы здесь

рабочее решение


import os
import sys

import pexpect


passphrase = os.environ['HOST_CA_KEY_PASSPHRASE']

command = 'ssh-keygen'
child = pexpect.spawn(command, args=sys.argv[1:])
child.expect('Enter passphrase:')
child.sendline(passphrase)

# Avoid Hang on macOS
# https://github.com/pytest-dev/pytest/issues/2022
while True:
    try:
        child.read_nonblocking()
    except Exception:
        break

if child.isalive():
    child.wait()
...