![](/img/trans.png)
[英]How to print output of pexpect consisting '\r' in next line of the terminal?
[英]Pexpect Mulitple Line Output
如何使用 pexpect 获得具有多行 output 的命令的 output?
此代码有效,尽管 output 被砸成一行:
child = pexpect.spawn('ping -c 3 1.1.1.1')
child.expect(pexpect.EOF)
print(child.before)
但是,此代码不起作用:
child = pexpect.spawn('hostname')
child.expect(pexpect.EOF)
print(child.before)
child.seldline('ping -c 3 1.1.1.1')
child.expect(pexpect.EOF)
print(child.before)
我将如何让第二个代码工作?
我有我需要运行才能连接的命令(此处替换为主机名),然后是 output 多行命令(此处替换为 ping),我似乎无法从中获取 output。 如果我查找 EOF 以外的任何字符串,我会收到 EOF 异常...
如果您需要证明,我实际运行的命令在这里:
这个其他问题的答案可能会被弃用,因为这部分代码完全复制只是一遍又一遍地输出b''
。
默认情况下,数据是bytes
,而不是str
。 这就是为什么“output砸成一行”的原因。 请参见以下示例:
$ cat foo.py
import pexpect
child = pexpect.spawn('ping -c 2 127.0.0.1')
child.expect(pexpect.EOF)
print(child.before)
$ python3 foo.py
b'PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.\r\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.027 ms\r\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.056 ms\r\n\r\n--- 127.0.0.1 ping statistics ---\r\n2 packets transmitted, 2 received, 0% packet loss, time 30ms\r\nrtt min/avg/max/mdev = 0.027/0.041/0.056/0.015 ms\r\n'
$
打印时可以decode()
:
$ cat foo.py
import pexpect
child = pexpect.spawn('ping -c 2 127.0.0.1')
child.expect(pexpect.EOF)
print(child.before.decode(encoding='utf8') ) # utf8 is the default for bytes.decode()
$ python3 foo.py
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.054 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 11ms
rtt min/avg/max/mdev = 0.024/0.039/0.054/0.015 ms
$
或者您可以在调用spawn()
时指定编码:
$ cat foo.py
import pexpect
child = pexpect.spawn('ping -c 2 127.0.0.1', encoding='utf8')
child.expect(pexpect.EOF)
print(child.before)
$ python3 foo.py
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.053 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 20ms
rtt min/avg/max/mdev = 0.036/0.044/0.053/0.010 ms
$
真正的问题:为什么第二个例子不起作用。
pexpect.spawn object(此处为“孩子”)指向进程 ID(PID)。 我尝试使用的示例不起作用,因为hostname
正在运行然后退出。 在我的实际用例中,我使用ssh
,然后在长 output 命令之前使用了其他几个必要步骤(在此处由ping
表示)。
使用持续运行的命令启动多步骤流程将解决该问题。 这些示例中的任何一个都可以使用:
child = pexpect.spawn('ssh user@host')
child = pexpect.spawn('bin/bash')
我切换到后者,它启动了一个我可以与之交互的新 shell。 这使我可以向 ssh 连接添加一些错误处理,并在一个 shell 中多次重用代码。
请注意,如果您分别退出 ssh 连接或 bash shell 连接,则需要生成一个新的“孩子”来发送更多命令。
额外细节:修复第一个/工作示例的 output。
A 此代码将返回最后一个命令的 output 而不会更改它。
def try_read(child):
"""Based on pexpect.pxssh.try_read_prompt"""
total_timeout = 3
timeout = 0.5
inter_char_timeout = 0.1
begin = time.time()
expired = 0
prompt = ''
while expired < total_timeout:
try:
prompt += child.read_nonblocking(size=1, timeout=timeout)
expired = time.time() - begin # updated total time expired
timeout = inter_char_timeout
except TimeoutError:
print("read ended with TimeoutError")
break
except pexpect.TIMEOUT:
print("read ended with pexpect.Timeout")
break
except pexpect.EOF:
print("read ended with pexpect.EOF")
break
return prompt
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.