首页 > 解决方案 > 如果输出很短,Pexpect 不会处理来自 python 脚本的输出,但适用于更长的输出

问题描述

所以,我正在尝试使用 pexpect 来驱动一些输出,并得到一些奇怪的结果。

为了测试,我有这个脚本,它只打印一些我期望的东西:

#!/usr/bin/env python3

for _ in range(4):
    print('test')
print('<<<canary>>>')
for _ in range(4):
    print('other stuff')
print('<<<end>>>')

然后我尝试在 ipython 会话中对此有所期待。但是,它似乎根本看不到它:

In [1]: import pexpect                                                                                                                                                                                                                                                  

In [2]: s = pexpect.spawn('./spawn_test.py', logfile=open('outfile.log', 'wb'))                                                                                                                                                                                         

In [3]: s.expect('<<<canary>>>')                                                                                                                                                                                                                                        
---------------------------------------------------------------------------
EOF                                       Traceback (most recent call last)
EOF: End Of File (EOF). Empty string style platform.

In [4]: s.before                                                                                                                                                                                                                                                        
Out[4]: b''

In [5]: s.buffer                                                                                                                                                                                                                                                        
Out[5]: b''

根本没有输出。但是,如果我只是在原始脚本中提高范围(例如,提高到 40000 而不是 4),那么它可以正常工作:

#!/usr/bin/env python3

for _ in range(40000):
    print('test')
print('<<<canary>>>')
for _ in range(40000):
    print('other stuff')
print('<<<end>>>')

然后

In [1]: import pexpect                                                                                                                                                                                                                                                  

In [2]: s = pexpect.spawn('./spawn_test.py', logfile=open('outfile.log', 'wb'))                                                                                                                                                                                         

In [3]: s.expect('<<<canary>>>')                                                                                                                                                                                                                                        
Out[3]: 0 (0x0)

In [4]: s.expect('<<<end>>>')                                                                                                                                                                                                                                           
Out[4]: 0 (0x0)

奇怪的是,即使它在第二种情况下有效(这证明该方法通常有效),在第一种情况下,脚本根本没有输出 - 我一直进入函数直到 os .read(self.fileno),它什么也没返回。这没有任何意义,所以我觉得我错过了一些东西。另外,在抛出 EOF 的期望之后s.terminatedFalse变为;并且在第一种情况下也不返回任何输出,但在第二种情况下工作正常。Trueread()readline()

这是在 OSX,python 3.7 上。

标签: pythonpexpect

解决方案


事实证明,这是 pexpect 的一个已知问题。解决方案似乎是用外壳包装命令,例如

s = pexpect.spawn('bash -c spawn_test.py')

不理想,但它确实解决了上述情况。

感觉这背后有一个不同的实际问题,但这种解决方法就足够了。


推荐阅读