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