我使用Paramiko向远程Linux服务器运行一些ssh命令。这些命令将在控制台中连续输出,我希望在本地控制台窗口中打印所有这些信息。
stdin, stdout, stderr = ssh.client.exec_command("ls")
for line in stdout.read()
print line,
ssh.client.close()
因此,如果我像这样编写代码,所有输出信息都将被发送回给我,直到命令执行完毕,而我想要在live中打印输出。
非常感谢。
发布于 2015-10-26 04:56:38
当然有一种方法可以做到这一点。Paramiko execute_command
是异步的,无论你的主线程是什么,数据到达时缓冲区都会被填充。
在您的示例中,stdout.read(size=None)
将尝试一次读取完整的缓冲区大小。因为新数据总是会到达,所以它永远不会退出。为了避免这种情况,您可以尝试以较小的块读取stdout
。下面是一个按字节读取缓冲区并在接收到\n
后生成行的示例。
stdin,stdout,stderr = ssh.exec_command("while true; do uptime; done")
def line_buffered(f):
line_buf = ""
while not f.channel.exit_status_ready():
line_buf += f.read(1)
if line_buf.endswith('\n'):
yield line_buf
line_buf = ''
for l in line_buffered(stdout):
print l
您可以通过调整代码以使用select.select()
和具有更大的块大小来提高性能,请参阅this answer,它还考虑了可能导致空响应的常见挂起和远程命令退出检测场景。
发布于 2022-02-23 19:40:42
因此,因为分享是关心的,所以我解决了PARAMIKO的问题,并像这样连续输出(忽略索引并替换内容,这是我设备的专有问题):
"elif action == "icmd":
cmd = command
channel = ssh.get_transport().open_session()
channel.exec_command(cmd)
channel.set_combine_stderr(True)
index = 0
a = "" # list to be filled with output of the commands.
while True:
if channel.exit_status_ready():
break
o = channel.recv(2048).decode("utf-8")
if o:
a += o
if "\n" in o:
b = a.split("\n")
a = b[-1]
b.pop()
for x in b:
print(x.replace("●", "").replace("└─", ""), flush=True)
index += 1
if index == 0 and len(o) > 0:
print(o.replace("●", "").replace("└─", ""), flush=True)
if index == 0 and len(o) == 0:
print(f"Your command '{cmd}' did not returned anything! ")
channel.close()
ssh.close()
“
我之所以选择拆分和弹出,是因为在使用诸如traceroute www.google.com之类的命令时,输出会被拆分成单独的行。
此外,我还集成了一个shell,用于与设备进行交互输入/输出,如下所示:
elif action == "shell":
channel = ssh.invoke_shell()
cmd = command
print("Shell started")
print(channel.recv(2048).decode())
while True:
if channel.exit_status_ready():
print("Session Ended!")
break
try:
cmd = input(cmd)
channel.send(f"{cmd}\n".encode())
time.sleep(1)
output = channel.recv(2048).decode("utf-8")
print(output.replace("●", "").replace("└─", ""), flush=True)
if cmd == "exit":
break
except KeyboardInterrupt:
break
channel.close()
ssh.close()
尽情享受吧!
https://stackoverflow.com/questions/25260088
复制相似问题