【问题标题】:python script: pexpect hangs on child.wait()?python 脚本:pexpect 挂在 child.wait() 上?
【发布时间】:2019-11-07 14:53:55
【问题描述】:
我在 Linux 中有一个创建 ssh-keys 的工作脚本。在 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()
【问题讨论】:
标签:
macos
python-3.7
pexpect
【解决方案1】:
终于,我找到了问题所在。貌似ssh-keygen二进制有点不一样,后面输出了一些东西。
因为 wait() 是一个阻塞调用。
这不会从孩子那里读取任何数据,所以如果孩子有未读的输出并且已经终止,这将永远阻塞。换句话说,孩子可能已经打印了输出,然后调用了 exit(),但是,孩子在技术上仍然活着,直到它的输出被父母读取。
.wait() docs here
为了解决这个问题,read_nonblocking 最多从子应用程序中读取 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()