Paramiko捕获命令输出

2024-09-19 14:28:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有个问题让我头痛了好几天。我将Paramiko模块与Python 2.7.10一起使用,我想向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\n')
# Check interface status.
remote_conn.send('show interfaces ethernet 0/1\n') # I only want output from this command.
time.sleep(2)
output = remote_conn.recv(5000)
print(output)

如果我要打印完整的输出,它将包含发送到路由器的所有内容,但我只想看到showinterfaces ethernet 0/1\n命令的输出。

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

最后一件事我想问。我想通过output变量进行筛选,并检查是否出现“up”或“down”之类的字符串,但我似乎无法使其工作,因为输出中的所有内容似乎都在新行上?

例如:

如果我在for循环中遍历output变量,我将获得变量中的所有字符,如下所示:

for line in output:
    print(line)

我得到这样的输出:

t型

e类

n个

一个

e类

n个

t型

小时

0个

有办法吗?

再一次

提前谢谢你的帮助。

谨致问候

亚伦·C


Tags: 命令sendparamikooutputremotetimeusername路由器
3条回答

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

#!/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\n')
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\n') # 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('\n'):
    if 'line protocol is up' in line:
        print(line)

现在一切都很好。

谢谢你的帮助。

谨致问候

亚伦·C

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

我还没有研究帕拉米科的建议。但是为什么不把整个字符串作为一个实体来处理呢?例如,您可以将“up”的存在检查为:

if "up" in output:

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

for line in output.split('\n'): 

如果可以的话,exec_command()调用提供了一种更简单的机制来调用命令。我见过Cisco交换机突然断开尝试exec_command()的连接,因此这可能无法用于Brocade设备。

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

相关问题 更多 >