python脚本:pexpect挂在child.wait()上吗? [英] python script: pexpect hangs on child.wait()?

查看:53
本文介绍了python脚本:pexpect挂在child.wait()上吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux中有一个工作脚本,可以创建ssh-key.在macOS中,它挂在wait()上.

I have a working script in Linux that creates ssh-keys. In macOS, it hangs on 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 二进制文件略有不同,并且它在之后输出了一些东西.

Finally, I found the problem. It seems that the ssh-keygen binary is slightly different, and it outputs some things after.

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

because wait() is a blocking call.

这不会从孩子那里读取任何数据,因此,如果孩子有未读的输出并终止了,则 这将永远阻塞 .换句话说,孩子可能已经打印了输出,然后称为exit(),但是,从技术上讲,孩子仍然活着,直到父母读取了其输出.

This will not read any data from the child, so this will block forever if the child has unread output and has terminated. In other words, the child may have printed output then called exit(), but, the child is technically still alive until its output is read by the parent.

.wait()此处的文档

为解决此问题,read_nonblocking从子应用程序中读取最大大小的字符.如果有可立即读取的字节,则将读取所有这些字节(最大为缓冲区大小).

to solve this problem read_nonblocking reads at most size characters from the child application. If there are bytes available to read immediately, all those bytes will be read (up to the buffer size).

.read_nonblocking()此处的文档

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

这篇关于python脚本:pexpect挂在child.wait()上吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆