Paramiko 捕获命令输出

Paramiko capturing command output

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

#!/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)

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

任何人都可以帮助解决这个问题吗?

我想问的最后一件事。我想过滤 output 变量并检查 "up" 或 "down" 等字符串的出现,但我似乎无法让它工作,因为输出中的所有内容似乎都是在新线路上?

例如:

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

for line in output:
    print(line)

我得到这样的输出:

t

e

r

n

一个

l

l

e

n

t

h

0

有什么解决办法吗?

再次,

在此先感谢您的帮助。

此致,

Aaron C.

关于你的第二个问题:虽然我不是paramiko专家,但我看到函数recv,according to the doc, returns a string. If you apply a for loop on a string, you will get characters (and not lines as one might perhaps expect). The newline is caused by your use of the print function as explained on this page, at paragraph 6.3

我还没有研究paramiko 建议做什么。但是为什么不将整个字符串视为一个实体呢?例如,您可以检查 "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 提示字符串。

阅读所有评论后,我进行了以下更改:

#!/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)

现在一切正常。

感谢大家的帮助。

此致,

A​​aron C.