使用Python庫paramiko登陸遠程設備

前言

手動下載paramiko庫的安裝包。在PyPi庫中查找便可,可是不到是個人電腦問題仍是網絡問題,2.0.0以上版本我都安裝不了,所以我本身是安裝的paramiko 1.17.0版本,此版本通過測試是能夠用的python

下載安裝paramiko

windows手動安裝,挺簡單的,只需找到解壓後安裝包的目錄,而後使用下面兩條命令便可shell

python setup.py build
python setup.py install

pip安裝,直接執行下面的命令,若是是虛擬環境,請先切換到虛擬環境後在安裝windows

pip install paramiko==1.17.0

使用paramiko登陸設備

使用paramiko庫登陸設備極其簡單並且能力很強,一般狀況下,使用secureCRT可以登陸到設備,就可以使用paramiko庫成功登陸。示例代碼以下:服務器

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/23 11:05 下午
# @Author : paul
# @Site : 
# @File : test.py


import paramiko

if __name__ == '__main__':
    hostname = '127.0.0.1'  # 主機名
    username = 'root'  # 用戶名
    password = '123456'  # 密碼

    # ssh login
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname=hostname, username=username, password=password, timeout=10)
    # 關閉鏈接
    ssh.close()

此段代碼經過我本身的服務器CentOS6.5進行測試,可使用。網絡

登陸成功以後,固然是但願能夠輸入命令來進行交互,以實現獲取系統數據。這裏總結了三種交互方式。ssh

paramiko和設備交互方式

一次輸入一個命令

如小標題所示,此中狀況爲只須要輸入一個命令,例如只是要獲取系統的某個參數。此時能夠採用相似SSHClient下的exec_command函數進行輸入,命令以字符串的形式表示。示例代碼以下:函數

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/23 11:17 下午
# @Author : paul
# @Site : 
# @File : test2.py


import paramiko

if __name__ == '__main__':
    hostname = '127.0.0.1'  # 主機名
    username = 'root'  # 用戶名
    password = '123456'  # 密碼

    # ssh login
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname=hostname, username=username, password=password, timeout=10)

    # 執行命令
    stdin , stdout , stderr = ssh.exec_command(cmd)
    # the stdin, stdout, and stderr of the executing command, as a 3-tuple
    # stdin : 輸入內容
    # stdout : 輸出內容
    # stderr : 錯誤信息
    print(stdout.read())
    ssh.close()

固然,這裏須要搞清楚,exec_command()方法也不是說只能執行一條命令,其實也能執行多條命令,可是這多條命令須要用&&符號拼接成一條命令,可是此種方式只能適用於命令提示符不變的狀況下:測試

cmd1 = 'cd /'
cmd2 = 'ls -l'
cmd = cmd1 + "&&" + cmd2

# 執行命令
stdin , stdout , stderr = ssh.exec_command(cmd)

一次輸入多個命令

此種方式能夠實現多個命令的方式,經過模擬輸入/輸出文件流與系統交互。ui

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/23 11:31 下午
# @Author : paul
# @Site : 
# @File : test3.py


import paramiko

if __name__ == '__main__':
    hostname = '127.0.0.1'  # 主機名
    username = 'root'  # 用戶名
    password = '123456'  # 密碼

    # ssh login
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname=hostname, username=username, password=password, timeout=10)

    channel = ssh.invoke_shell()
    stdin = channel.makefile('wb') # 輸入流
    stdout = channel.makefile('rb') # 輸出流
    
    stdin.write('cd /home\rls\rexit\r') # 輸入須要加入回車符號
    print(stdout.read())
    
    ssh.close()

輸入命令有stdin.write(command)來完成,須要注意的是,這種交互方式進行交互的話,須要一次性將命令寫完,包括退出命令exit(不一樣系統有不一樣的退出命令),每一個命令用\r(回車符)表示結束。code

屢次輸入/輸出交互

1.類channel中的send(command)函數爲屢次交互提供了便利

2.命令以字符串的形式輸入,須要使用"\r"做爲結尾,可是不須要系統登出命令做爲全部命令的結尾。

3.能夠實現命令交互,可是須要結合recv_read()方法進行,即當容許讀的時候再進行讀取。

以下提供了一個多命令交互的示例。await_command(channel)爲等待是否可以讀取的函數,receive_data(channel)爲能夠讀取以後,讀取輸入命令以後的數據。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/23 11:49 下午
# @Author : paul
# @Site : 
# @File : test4.py

import paramiko
import time


def await_command(channel):
    while True:
        if channel.recv_ready():
            return True
        else:
            time.sleep(0.5)
        return False


def receive_data(channel):
    all_data = str()
    while True:
        tmp_data = channel.recv(1024)
        all_data += tmp_data
        # 這裏的結束循環的條件能夠根據實際狀況來設定
        if "#" in all_data:
            break
    return all_data


if __name__ == '__main__':
    hostname = '127.0.0.1'  # 主機名
    username = 'root'  # 用戶名
    password = '123456'  # 密碼

    try:
        # ssh login
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname=hostname, username=username, password=password, timeout=10)
        # 建立一個面板用來顯示交互
        channel = ssh.invoke_shell()

        # 發送命令,接收數據
        channel.send('cd /home\r')
        await_command(channel)
        print(receive_data(channel))

        channel.send('ls -l\r')
        await_command(channel)
        print(receive_data(channel))

        ssh.close()
    except Exception as e:
        raise Exception('connect error')

若是須要進行一行一行的讀取時,也能夠將makefile應用過來,以下:

def receive_data(channel):
    reader = channel.makefile()
    while True:
        line = reader.readline()
        print(line)
        if '#' in line:
            break
    return line

總結

parmiko庫是一個功能很強大的庫,爲咱們提供了不少的交互方式,可是實際上咱們須要根據本身的應用選擇合適的交互方式,合適的纔是最好的。

相關文章
相關標籤/搜索