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()
