Paramiko捕获命令输出

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Paramiko捕获命令输出相关的知识,希望对你有一定的参考价值。

我有一个让我头疼几天的问题。我在Python 2.7.10中使用Paramiko模块,我想向Brocade路由器发出多个命令,但只返回给定命令之一的输出,如下所示:

#!/usr/bin/env python
import paramiko, time

router = 'r1.test.example.com'
password = 'password'
username = 'testuser'

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(router, username=username, password=password)
print('Successfully connected to %s' % router)

remote_conn = ssh.invoke_shell()
output = remote_conn.recv(1000)

# Disable paging on Brocade.
remote_conn.send('terminal length 0
')
# Check interface status.
remote_conn.send('show interfaces ethernet 0/1
') # I only want output from this command.
time.sleep(2)
output = remote_conn.recv(5000)
print(output)

如果我打印完整输出它将包含发给路由器的所有内容,但我只想查看show interfaces ethernet 0/1 命令的输出。

有人可以帮忙解决这个问题吗?

最后我想问一下。我想过滤output变量并检查字符串的出现,如“向上”或“向下”,但我似乎无法让它工作,因为输出中的所有内容都显示在新行上?

例如:

如果我在for循环中迭代output变量,我会得到变量中的所有字符,如下所示:

for line in output:
    print(line)

我得到这样的输出:

Ť

[R

一世

ñ

一个

ñ

G

Ť

H

0

有什么方法吗?

再次,

在此先感谢您的帮助。

最好的祝福,

亚伦C.

答案

对于你的第二个问题:虽然我不是paramiko的专家,但我看到函数recv,according to the doc,返回一个字符串。如果在字符串上应用for循环,则会获得字符(而不是人们可能期望的行)。换行是由您使用打印功能引起的,如on this page, at paragraph 6.3所述。

我还没有研究过paramiko建议做什么。但是为什么不将完整字符串视为单个实体?例如,您可以检查“up”的存在,如下所示:

if "up" in output:

或者,如果这更适合您的需求,您可以split the string into lines然后做您想做的任何测试:

for line in output.split('
'): 
另一答案

阅读完所有评论后,我做了以下更改:

#!/usr/bin/env python
import paramiko, time

router = 'r2.test.example.com'
password = 'password'
username = 'testuser'

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(router, username=username, password=password)
print('Successfully connected to %s' % router)

remote_conn = ssh.invoke_shell()
output = remote_conn.recv(1000)

# Disable paging on Brocade.
remote_conn.send('terminal length 0
')
time.sleep(2)
# Clearing output.
if remote_conn.recv_ready():
    output = remote_conn.recv(1000)

# Check interface status.
remote_conn.send('show interfaces ethernet 4/1
') # I only want output from this command.
time.sleep(2)
# Getting output I want.
if remote_conn.recv_ready():
    output = remote_conn.recv(5000)
print(output)

# Test: Check if interface is up.
for line in output.split('
'):
    if 'line protocol is up' in line:
        print(line)

现在一切都很好。

谢谢你的帮助。

最好的祝福,

亚伦C.

另一答案

如果可以,exec_command()调用提供了一种更简单的机制来调用命令。我看到思科交换机突然丢弃尝试exec_command()的连接,因此可能无法与Brocade设备一起使用。

如果你必须去invoke_shell()路线,请务必在连接之后和send('terminal length 0 ')之后清除所有待处理的输出,在调用recv_ready()之前检查recv()以避免阻止读取可能无法到达的数据。由于您正在控制交互式shell,因此可能需要sleep()调用以允许服务器有足够的时间来处理和发送数据,或者可能需要轮询输出字符串以通过识别shell提示字符串来确认您的上一个命令已完成。

以上是关于Paramiko捕获命令输出的主要内容,如果未能解决你的问题,请参考以下文章

代码中异常捕获输出

使用 FFmpeg 通过管道输出视频片段

SSH 窗口大小如何影响 paramiko

如何从 paramiko 的标准输出中删除坏字符 [重复]

读取在 SSH 服务器上执行的命令的输出,使用 Paramiko 作为字符串,而不是字节

paramiko模块