读取在 SSH 服务器上执行的命令的输出,使用 Paramiko 作为字符串,而不是字节
Posted
技术标签:
【中文标题】读取在 SSH 服务器上执行的命令的输出,使用 Paramiko 作为字符串,而不是字节【英文标题】:Read output of a command executed on SSH server with Paramiko as string, not as bytes 【发布时间】:2021-07-14 03:18:28 【问题描述】:几年前我在 Python 2.x 中编写了一个脚本,并试图将其移植到 3.x 中运行
以下是我正在做的基本工作:NetworkDevices
是一个包含设备列表的主机和访问凭据的文件。DebugFile
是一个输出文件go(取决于调试级别),因此我可以看到设备何时发送了我不期望的内容。
NetworkDevices = open(WorkingDir + DeviceFilename,"r")
DebugFile = open(WorkingDir + DebugFilename,"w",1)
Try
# Create instance of SSHClient object
ssh_pre = paramiko.SSHClient()
# Automatically add untrusted hosts (make sure okay for security policy in your environment)
ssh_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# initiate SSH connection
ssh_pre.connect(InputVars[0], username=InputVars[1], password=InputVars[2], timeout=10)
# Use invoke_shell to establish an 'interactive session'
Conn = ssh_pre.invoke_shell()
except
# SSH connection failed, lets try a telnet connection.
Conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Open Telnet Connection to device
Conn.connect((InputVars[0],23))
except
#Print some error message saying you couldn't connect, blah blah
else
output = str(Conn.recv(10000))
else
output = str(Conn.recv(10000))
# After I establish my connection via object Conn, I can always just pull more data from
# the same connection object regardless of whether it's ssh or telnet.
if DebugVar > 3:
DebugFile.write("Here is the initial response after connecting.\n")
DebugFile.write("<<<1>>>\n"+output+"\n<<<1>>>\n")
然后根据要收集的内容、设备类型等做一堆事情。
我得到的输出是这样的:
Here is the initial response after connecting:
<<<1>>>
b'\r\nUShaBTC-DCTNW-CORE01#'
<<<1>>>
我想得到这个:
Here is the initial response after connecting.
<<<1>>>
UShaBTC-DCTNW-CORE01#
<<<1>>>
我尝试过使用格式化的字符串文字,但这一直在引导我使用字符串切片,这是我试图避免的。这是我正在尝试做的一件非常简单的事情。接收“块”(使用通用术语)数据,在该数据中查找某个字符串、关键字或结构,然后向连接发送一些内容,并获取另一块数据。
是的,我正在寻找的是我收到的任何一种方式。我仍然可以搜索它,但在某些时候我需要将收到的内容写入一个可读的文件中,而我这样做的运气并不好。
嘿,还有一个问题.... 显然 Python 3 不支持无缓冲文件输出。正如我所展示的,我将数据转储到调试文件中(取决于我的脚本运行的调试级别)。在崩溃中,获取我收到的最后一点数据以找出崩溃的原因非常重要,因此我总是将立即收到的数据写入我的调试文件而不缓冲,这样我以后可以弄清楚它在哪里崩溃以及为什么.有没有办法在没有缓冲的情况下在 Python 3 中写入文件?我回退到 1(而不是 0)的缓冲区,所以我的脚本将在 Python 3.x 中运行,但我仍然可能看不到最后一个(我猜是 1 个字节,实际上无法找出单位是针对那个缓冲区大小的)。
感谢任何帮助。
【问题讨论】:
【参考方案1】:只需在字节串上调用decode
:
output = Conn.recv(10000).decode('utf-8')
虽然一般来说,你不应该使用SSHClient.invoke_shell
。使用SSHClient.exec_command
。见What is the difference between exec_command and send with invoke_shell() on Paramiko?
【讨论】:
谢谢马丁。我终于发现我试图在将类型转换为 str 后对其进行解码,这当然不起作用。一旦我让解码器对 str 进行强制转换,它现在就可以工作了。以上是关于读取在 SSH 服务器上执行的命令的输出,使用 Paramiko 作为字符串,而不是字节的主要内容,如果未能解决你的问题,请参考以下文章