python 脚本:pexpect 在 child.wait() 上挂起?

python script: pexpect hangs on child.wait()?

我在 Linux 中有一个创建 ssh 密钥的工作脚本。在 macOS 中,它挂在 wait() 上。

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()

终于找到问题了。 ssh-keygen binary好像有点不一样,后面输出了一些东西。

因为 wait() 是一个阻塞调用。

这不会从 child 读取任何数据,所以 如果 child 这将永远阻塞 ] 有未读输出并已终止。换句话说,child 可能打印输出然后调用 exit(),但是,child 在技术上仍然有效,直到它的输出被 parent.

读取。

.wait() docs here

解决此问题 read_nonblocking 从 child 应用程序读取最多 size 个字符。如果有可立即读取的字节,将读取所有这些字节(直到缓冲区大小)。

.read_nonblocking() docs here

工作解决方案


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()