Paramiko使用


1、下載安裝 pycrypto-2.6.1.tar.gz  (apt-get install python-dev)

    解壓,進入,python setup.py build【編譯】,python setup.py install 【安裝】  ----》import Crypto

  2、下載安裝 paramiko-1.10.1.tar.gz  

    解壓,進入,python setup.py build【編譯】,python setup.py install 【安裝】---》  import paramiko

 

 

1、連接遠程服務器,並執行操作
用戶名和密碼連接1

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.10.50.30', 22, 'root', '123456')
stdin, stdout, stderr = ssh.exec_command('ifconfig')
print stdout.read()
ssh.close();
用戶名和密碼連接2  (SSHClient 封裝 Transport)推薦

 

transport = paramiko.Transport(('10.10.50.30', 22))
transport.connect(username='root', password='jichuang')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('ifconfig')
print stdout.read()
transport.close()

 

 
        

公鑰私鑰鏈接
ssh-keygen -t rsa
ssh-copy-id -i .ssh/id_rsa.pub "-p 22 root@10.10.50.30"

import paramiko
private_key_path = '/root/.ssh/id_rsa' #本機私鑰存放位置
key = paramiko.RSAKey.from_private_key_file(private_key_path)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.10.50.31 ', 22, 'root' ,pkey=key)
stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()
ssh.close();

  

公鑰私鑰鏈接2 (SSHClient 封裝 Transport)推薦

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')
transport = paramiko.Transport(('10.10.50.30', 22))
transport.connect(username='root', pkey=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
transport.close()

  

2、SFTP上傳下載
基於用戶名和密碼
import os,sys
import paramiko
t = paramiko.Transport(('10.10.50.30',22))
t.connect(username='yangmv',password='123456')
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('C:\Users\yangmingwei\Desktop\error.jpg','/home/yangmv/error.jpg')
#將error.jpg上傳到服務器/home/yangmv目錄
sftp.get('/home/yangmv/sftp.txt','C:\Users\yangmingwei\Desktop\sftp.txt')
#將sftp.txt下載到本機桌面
t.close()

  

基於公鑰秘鑰上傳下載
import paramiko
 
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='yangmv', pkey=private_key )
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
 
transport.close()

  

 
 
Paramiko 批量執行命令
版本一:
缺點: 每次執行一個操作,就要進行一次連接
import paramiko
import uuid
class Comm(object):
    def __init__(self):     #初始化參數
self.host = '10.10.50.30'
self.port = 22
self.username = 'root'
self.pwd = '123456'
self.file_name = ''

def create_file(self):  #本地創建文件
file_name = str(uuid.uuid4())   #uuid創建一個不會重復的隨機字符串作為文件名
with open(file_name,'w') as f_obj:
            f_obj.write('sb')
        return file_name    #返回文件名
def run(self):
        self.upload()       #執行上傳
self.rename()       #執行重命名
        
def upload(self):       #用於上傳
self.file_name = self.create_file()
        t = paramiko.Transport((self.host,self.port))
        t.connect(username=self.username,password=self.pwd)
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.put(self.file_name,'/home/yangmv/%s'%self.file_name)
        t.close()
    def rename(self):       #用於重命名
ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(self.host, self.port, self.username, self.pwd)
        stdin, stdout, stderr = ssh.exec_command('mv /home/yangmv/%s /home/yangmv/xxxx.txt'%(self.file_name))
        print stdout.read()
        ssh.close();
startcmd = Comm()
startcmd.run()

  


版本二:(推薦)
優點:不管執行多少個操作,都只連接一次
import paramiko
import uuid
class Comm(object):
    def __init__(self):     #初始化參數
self.host = '10.10.50.30'
self.port = 22
self.username = 'root'
self.pwd = '123456'

def create_file(self):  #本地創建文件
file_name = str(uuid.uuid4())   #uuid創建一個不會重復的隨機字符串作為文件名
with open(file_name,'w') as f_obj:
            f_obj.write('sb2')
        return file_name    #返回文件名
def run(self):
        self.connect()
        self.upload()       #執行上傳
self.rename()       #執行重命名
self.close()

    def connect(self):        #用於ssh連接
t = paramiko.Transport((self.host,self.port))
        t.connect(username=self.username,password=self.pwd)
        self.__transport = t
    def close(self):          #用於ssh關閉
self.__transport.close()
    def upload(self):       #用於上傳
self.file_name = self.create_file()
        sftp = paramiko.SFTPClient.from_transport(self.__transport)
        sftp.put(self.file_name,'/home/yangmv/%s'%self.file_name)
    def rename(self):       #用於重命名
ssh = paramiko.SSHClient()
        ssh._transport = self.__transport
        stdin, stdout, stderr = ssh.exec_command('mv /home/yangmv/%s /home/yangmv/ssss.txt'%self.file_name)
        result = stdout.read()
startcmd = Comm()
startcmd.run()

  

 
Paramiko持續連接服務器1 select
import paramiko
import select   #無法在windows下操作
import sys
t = paramiko.Transport(('10.10.50.31', 22))
t.start_client()
#基於公鑰驗證
##default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
#key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')
#t.auth_publickey('root',key)
#基於用戶密碼驗證
t.auth_password('root', '123456')

#打開一個通道
chan = t.open_session()
#獲取一個終端
chan.get_pty()
#激活器
chan.invoke_shell()

#########
# 利用sys.stdin,肆意妄為執行操作
# 用戶在終端輸入內容,並將內容發送至遠程服務器
# 遠程服務器執行命令,並將結果返回
# 用戶終端顯示內容
while True:
    # 監視用戶輸入和服務器返回數據
# sys.stdin 處理用戶輸入
# chan 是之前創建的通道,用於接收服務器返回信息
r_list,w_list,error = select.select([chan,sys.stdin,],[],[],1)
    if chan in r_list:                  #接收命令執行后返回的結果
try:
            x = chan.recv(1024)
            if len(x) == 0:
                print '\r\n*** EOF\r\n',
break
sys.stdout.write(x)
            sys.stdout.flush()
        except socket.timeout:
            pass
    if sys.stdin in r_list:             #用戶輸入
inp = sys.stdin.readline()
        chan.sendall(inp)               #把用戶輸入命令發送執行
#########
chan.close()
t.close()

  

成功登陸機器,並可以持續連接,不斷輸入命令,並到達返回結果
 
Paramiko持續連接服務器2  改進
1的缺點:
    輸入端,以行為單位,敲回車后才執行命令     ( ls + 回車 → 發送遠端)
    無法使用tab補全
2的改進:
    改變默認終端,由 行stdin, 一個字符stdin     ( l    → 發送 遠端 ,s   → 發送 遠端   
    每輸入一次,向遠端發送一次 
     無法使用tab補全
import paramiko
import select   #無法在windows下操作
import sys
import termios
import tty

t = paramiko.Transport(('10.10.50.31', 22))
t.start_client()
#基於公鑰驗證
##default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
#key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')
#t.auth_publickey('root',key)
#基於用戶密碼驗證
t.auth_password('root', '123456')

#打開一個通道
chan = t.open_session()
#獲取一個終端
chan.get_pty()
#激活器
chan.invoke_shell()

#########
#獲取原tty屬性
oldtty = termios.tcgetattr(sys.stdin)
try:
    # 為tty設置新屬性
# 默認當前tty設備屬性:
# 輸入一行回車,執行
# CTRL+C 進程退出,遇到特殊字符,特殊處理。
# 這是為原始模式,不認識所有特殊符號
# 放置特殊字符應用在當前終端,如此設置,將所有的用戶輸入均發送到遠程服務器
tty.setraw(sys.stdin.fileno())
    chan.settimeout(0.0)
    while True:
        #監視用戶輸入和遠程服務器的返回數據socket
        #阻塞,直到句柄可用
r_list,w_list,error = select.select([chan,sys.stdin,],[],[],1)
        if chan in r_list:
            try:
                x = chan.recv(1024)
                if len(x) == 0:
                    print '\r\n*** EOF\r\n',
break
sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in r_list:
            inp = sys.stdin.read(1)     #每次讀1個字符
if len(inp) == 0:
                break
chan.sendall(inp)
finally:
    #退出后恢復終端屬性
termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty)

#########
chan.close()
t.close()

  

 
        
 
Paramiko持續連接服務器3  記錄操作日志
import paramiko
import select   #無法在windows下操作
import sys
import termios
import tty

t = paramiko.Transport(('10.10.50.31', 22))
t.start_client()
t.auth_password('root', '123456')

chan = t.open_session()
chan.get_pty()
chan.invoke_shell()

#########
oldtty = termios.tcgetattr(sys.stdin)
try:
    tty.setraw(sys.stdin.fileno())
    chan.settimeout(0.0)
    f  = open('record.log','a')
    records = []
    while True:
        r_list,w_list,error = select.select([chan,sys.stdin,],[],[],1)
        if chan in r_list:
            try:
                x = chan.recv(1024)
                if len(x) == 0:
                    print '\r\n*** EOF\r\n',
f.close()   #異常中斷,或者exit退出時保存
break
sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in r_list:
            inp = sys.stdin.read(1)
            records.append(inp)  #把個字符鍵入列表暫時保存 ['l','s']
if len(inp) == 0:
                break
            if inp == '\t':     #tab鍵不記錄
pass
            if inp == '\r':     #每次回車
cmd = ''.join(records).replace('\r','\n') #[ls]+換行
f.write(cmd)
                records = []    #每次記錄一個條命令
chan.sendall(inp)
finally:
    termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty)
#########
chan.close()
t.close()

  

成功記錄
 
Paramiko持續連接服務器4 適用windows
import paramiko
import sys
import threading

t = paramiko.Transport(('10.10.50.31', 22))
t.start_client()
t.auth_password('root', '123456')

chan = t.open_session()
chan.get_pty()
chan.invoke_shell()

#########
sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")
def writeall(sock):
    while True:
        data = sock.recv(256)
        if not data:
            sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
            sys.stdout.flush()
            break
sys.stdout.write(data)
        sys.stdout.flush()

writer = threading.Thread(target=writeall, args=(chan,))
writer.start()

try:
    while True:
        d = sys.stdin.read(1)
        if not d:
            break
chan.send(d)
except EOFError:
    # user hit ^Z or F6
pass
#########
chan.close()
t.close()

  

 
 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM