![](/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.