1. 程式人生 > 程式設計 >python中使用paramiko模組並實現遠端連線伺服器執行上傳下載功能

python中使用paramiko模組並實現遠端連線伺服器執行上傳下載功能

paramiko模組

paramiko是一個用於做遠端控制的模組,使用該模組可以對遠端伺服器進行命令或檔案操作,paramiko是用python語言寫的一個模組,遵循SSH2協議,支援以加密和認證的方式,進行遠端伺服器的連線。

由於使用的是python這樣的能夠跨平臺執行的語言,所以所有python支援的平臺,如Linux,Solaris,BSD,MacOS X,Windows等,paramiko都可以支援,因此,如果需要使用SSH從一個平臺連線到另外一個平臺,進行一系列的操作時,paramiko是最佳工具之一。

因此,如果需要使用SSH從一個平臺連線到另外一個平臺,進行一系列的操作時,paramiko是最佳工具之一。

通過ssh連結伺服器並執行想要的命令,類似於XShell

ansible(遠端批量管理伺服器)底層原始碼其實就是paramiko模組實現的

安裝

pip3 install paramiko

使用

前提須知:paramiko模組即支援使用者名稱密碼的方式,也支援公鑰私鑰的方式操作伺服器

1.使用者名稱密碼的方式:

# 執行命令
import paramiko
# 建立連結物件
ssh = paramiko.SSHClient()
# 允許連結不在know_hosts檔案中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連結伺服器
ssh.connect(hostname='伺服器ip地址',port='埠號',username='使用者名稱',password='密碼')
# 執行命令
stdin,stdout,stderr = ssh.exec_command('ip a')
"""
stdin 是用來輸入額外的引數的  -y
stdout 命令的返回結果
stderr 錯誤的結果
"""
# 獲取命令執行的結果
res = stdout.read()
print(res.decode('utf-8'))
# 關閉連結
ssh.close()

2.公鑰私鑰的方式

首先在windows上產生公鑰私鑰對

可以用openssl工具產生,也可以用Git Bash工具產生(需要安裝git)
1.開啟 Git Bash工具 輸入命令 ssh-keygen
2.輸入完命令一直按回車即可
3.在 c/user/使用者名稱下的檔案/.ssh 的目錄中生成了兩個金鑰檔案。id_rsa 為私鑰,id_rsa.pub 為公鑰
4.將公鑰內容複製到你的linux伺服器下的 /root/.ssh/authorized_keys檔案中即可

複製私鑰檔案到專案根目錄下,我這裡重新命名為a.txt

import paramiko
# 讀取本地私鑰
private_key = paramiko.RSAKey.from_private_key_file('a.txt')
# 建立SSH物件
ssh = paramiko.SSHClient()
# 允許連線不在know_hosts檔案中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連線伺服器
ssh.connect(hostname='伺服器ip地址',port=22,pkey=private_key)
# 執行命令
stdin,stderr = ssh.exec_command('ls /')
# 獲取命令結果
result = stdout.read()
print(result.decode('utf-8'))
# 關閉連線
ssh.close()

實現上傳下載檔案

1.使用者名稱和密碼的方式:

import paramiko
# 使用者名稱和密碼
transport = paramiko.Transport(('伺服器ip地址',22))
transport.connect(username='使用者名稱',password='密碼')
sftp = paramiko.SFTPClient.from_transport(transport)
# 上傳檔案
# sftp.put("a.txt",'/data/tmp.txt') # 注意上傳檔案到遠端某個檔案下 檔案必須存在
# 下載檔案
sftp.get('/data/tmp.txt','hahaha.txt') # 將遠端檔案下載到本地並重新命令
transport.close()

2.公鑰和私鑰的方式:

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('a.txt')
transport = paramiko.Transport(('伺服器地址',pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至伺服器 /tmp/test.py
sftp.put('manage.py','/data/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path','local_path')
transport.close()

下面將執行命令和上傳下載檔案 封裝到一個類裡面

SSHProxy類的封裝

假如我想連結伺服器執行三條命令,並且上傳一個檔案內容

大部分都會操作幾次就連結幾次伺服器,效率較低,程式碼冗餘

我們想實現一個類裡面包含了執行命令和上傳下載檔案的操作

# 類的程式碼無需掌握 只需要會拷貝使用即可
import paramiko
class SSHProxy(object):
  # 這裡的引數 你可以再加公鑰私鑰的形式
  def __init__(self,hostname,port,username,password):
    self.hostname = hostname
    self.port = port
    self.username = username
    self.password = password
    self.transport = None
  def open(self): # 給物件賦值一個上傳下載檔案物件連線
    self.transport = paramiko.Transport((self.hostname,self.port))
    self.transport.connect(username=self.username,password=self.password)
  def command(self,cmd): # 正常執行命令的連線 至此物件內容就既有執行命令的連線又有上傳下載連結
    ssh = paramiko.SSHClient()
    ssh._transport = self.transport
    stdin,stderr = ssh.exec_command(cmd)
    result = stdout.read()
    return result
  def upload(self,local_path,remote_path):
    sftp = paramiko.SFTPClient.from_transport(self.transport)
    sftp.put(local_path,remote_path)
    sftp.close()
  def close(self):
    self.transport.close()
  def __enter__(self): # 物件執行with上下文會自動觸發
    self.open()
    return self # 這裡發揮上面with語法內的as後面拿到的就是什麼 
  def __exit__(self,exc_type,exc_val,exc_tb): # with執行結束自動觸發
    self.close()

使用流程

"""
上述的封裝操作在使用的使用 必須按照下面的順序
obj = SSHProxy(...)
obj.open() # 產生的物件必須要先執行open方法
obj.command('ls /')
obj.command('cat /data/tmp.txt')
obj.upload(...)
obj.upload(...)
obj.close()

利用檔案操作的特性
f = open()
f.close()
嫌上述操作麻煩 利用with上下文做處理了
with open() as f:
  pass
as後面的值由__enter__方法返回值決定 返回什麼就是什麼

# 一旦物件被執行with會自動觸發物件內部的__enter__方法 with結束之後還會自動觸發__exit__方法
obj = SSHProxy(1,2,3,4)
with obj as f:
  pass

封裝之後按照下面的方式使用即可

with SSHProxy(....) as obj:
  obj.command()
  obj.command()
  obj.upload()
  obj.upload()
  obj.command()
"""

拓展: __enter__ 和 __exit__ 的使用

class Foo(object):
  def __enter__(self):
    print('他進來了')
    return 123
  def __exit__(self,exc_tb):
    print('他就這麼出去了')
obj = Foo()
with obj as f:
  print(f)
"""
執行結果:
他進來了
123
他就這麼出去了
"""

總結:as後面的值由__enter__ 方法返回值決定 返回什麼就是什麼,

​ 一旦物件被執行with會自動觸發物件內部的__enter__ 方法 with結束之後還會自動觸發__exit__ 方法

面試題

# 面試題"""
請在Context類中新增程式碼完成該類的實現(意思是怎麼樣修改才能實現以下程式碼並不會報錯)
"""
class Context:
 pass
with Context() as ctx:
 ctx.do_something()
# 答案
class Context:
 def __enter__(self):
    return self
  def __exit__(self,*args,**kwargs):
    pass
 def do_something(self):
    pass

到此這篇關於python中使用paramiko模組並實現遠端連線伺服器執行上傳下載功能的文章就介紹到這了,更多相關python paramiko模組內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!