使用argparse,paramiko兩個包去實現簡易的服務器管理器,完成兩種方式的連接( 密碼和密鑰 ),以及命令行交互,文件上傳下載。
相比sys.argv的方式去判斷傳入的參數,如果參數較多那么argparse包更易維護和修改,遠程控制模塊paramiko可以很輕易的實現遠控的功能
注意:paramiko中的SSHClient對象的exec_command在執行cd命令的時候沒有效果,需要和其它命令一起執行,
例如:stdin, stdout, stderr = client.exec_command('cd test; ls')
話不多說,直接上代碼:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:Riy 4 5 6 import logging 7 import argparse 8 import paramiko 9 10 11 logging.basicConfig( 12 level=logging.DEBUG, 13 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 14 filename='SSHlog.log', 15 filemode='a' 16 ) 17 18 19 class RiySSH: 20 def ssh_parse(self): 21 '''設置參數''' 22 parser = argparse.ArgumentParser("Riy command line ssh server operate 服務器操作命令行工具...") 23 parser.add_argument('-H', '--host', dest="HOST", action="store", help="要連接的主機") 24 parser.add_argument('-P', '--port', dest="PORT", action="store", help="連接主機的端口") 25 parser.add_argument('-u', '--username', dest="USER", action="store", help="連接的用戶名") 26 parser.add_argument('-p', '--password', dest="PWD", action="store", help="使用密碼進行認證") 27 parser.add_argument('-s', '--ssh', dest="SSH", action="store", help="使用密鑰文件進行認證") 28 parser.add_argument('--shell', dest="SHELL", action="store_true", help="進入命令交互模式") 29 parser.add_argument('-U', '--upload', dest="UPLOAD", nargs="*", help="上傳文件,需要追加文件名") 30 parser.add_argument('-D', '--download', dest="DOWNLOAD", nargs="*", help="下載文件,需要追加文件名") 31 parser.print_help() 32 args = parser.parse_args() 33 return args 34 35 def connect_password(self, HOST, PORT, USER ,PWD=None, SSH=None): 36 '''進行服務器連接''' 37 client = paramiko.SSHClient() 38 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 39 private = paramiko.RSAKey.from_private_key_file(SSH) 40 client.connect(hostname=HOST, port=PORT, username=USER, password=PWD, pkey=private) 41 return client 42 43 def connect_cmd(self, client): 44 '''命令行交互''' 45 while True: 46 print('請輸入shell命令,按q鍵退出:') 47 CMD = input('>>') 48 stdin, stdout, stderr = client.exec_command(CMD) 49 print(stdout.read().decode('utf-8')) 50 if CMD == 'q': 51 break 52 53 def download_file(self, client, remote_file_path, local_file_path): 54 '''下載文件''' 55 ftp_client = client.open_sftp() 56 ftp_client.get(remote_file_path, local_file_path) 57 58 def upload_file(self, client, local_file_path, remote_file_path): 59 '''上傳文件''' 60 ftp_client = client.open_sftp() 61 ftp_client.put(local_file_path, remote_file_path) 62 63 64 def main(): 65 a = RiySSH() 66 args = a.ssh_parse() 67 if args.PWD or args.SSH: 68 HOST = args.HOST 69 PORT = args.PORT 70 USER = args.USER 71 PWD = args.PWD 72 SSH = args.SSH 73 client = a.connect_password(HOST, PORT, USER, PWD, SSH) 74 if args.UPLOAD: 75 a.upload_file(client, args.UPLOAD[0], args.UPLOAD[1]) 76 if args.DOWNLOAD: 77 a.download_file(client, args.DOWNLOAD[0], args.DOWNLOAD[1]) 78 if args.SHELL: 79 a.connect_cmd(client) 80 client.close() 81 82 83 if __name__ == '__main__': 84 main()