• day13 使用sqlalchemy和paramiko实现一个简单的跳板机


    代码如下(未使用sqlalchemy版本):

    #!/bin/env python
    
    import paramiko
    import sys
    import os
    import socket
    import getpass
    
    from paramiko.py3compat import u
    
    import termios    #Windows下无此模块
    import tty
    import select
    
    
    '''
    有关终端模式的解释
    终端最常用的模式是Cooked模式,在该模式下删除键和终止键能正常地工作,CTRL_S和 CTRL_Q用来停止和恢复终端输出,
    CTRL_D为文件结束符,按DEL键产生一个中断信号,而CTRL-产生一个退出信号并强制进行核心映像转储。
    
    在raw模式下,所有这些功能都被取消,每个字符都被不加处理地送给程序,而且不等一行结束就将从终端读到每一个字符
    发送给程序。与此不同的是在Cooked模式下,终端输入的数据等到一行结束才送给程序。
    
    Cbreak模式介于上述两者之间,用作编辑的删除键和终止键,以及CTRL_D被屏蔽,但CTRL_S,CTRL_Q,DEL和CTRL_则仍然
    有效,与raw模式一样,单个字符不等一行结束就送给程序(如果禁止行内编辑功能,则没必要等待接收到完整的一行,因为
    用户不可能象在cooked模式下那样改变主意并删除它)。
    '''
    
    
    def posix_shell(chan):
    
        oldtty = termios.tcgetattr(sys.stdin)   #获取当前终端的模式
        try:
            tty.setraw(sys.stdin.fileno())    #设置终端模式为raw模式
            tty.setcbreak(sys.stdin.fileno())   #设置终端模式为cbreak模式
            chan.settimeout(0.0)     #不对chan超时时间做限制
            log = open('handle.log', 'a+', encoding='utf-8')    #open一个文件,用来记录历史命令
            flag = False
            #当用户输入table键时,flag才为True,当有内容返回时,判断flag是否为True,如果为True,
            # 如果返回值.startswith('
    ')为空,不做任何操作,如果返回值不为空,将返回值加到temp_list列表
            # 中(因为返回值是用户敲命令是补全的命令后半截)
            temp_list = []   #用来存放用户输入,即记录历史命令
            while True:
                r, w, e = select.select([chan, sys.stdin], [], [])
                if chan in r:    #chan in  r时,说明有返回值
                    try:
                        x = u(chan.recv(1024))   #获取返回内容
                        if len(x) == 0:   #如果返回值长度为0,代表用户输入exit退出了
                            sys.stdout.write('
    *** EOF
    ')
                            break
                        if flag:     #上方定义flag时已解释
                            if x.startswith('
    '):
                                pass
                            else:
                                temp_list.append(x)
                            flag = False  #最后将flag还原为False
                        sys.stdout.write(x)    #输出返回值到屏幕
                        sys.stdout.flush()
                    except socket.timeout:
                        pass
                if sys.stdin in r:    #sys.stdin in r时,说明用户用输入内容
                    x = sys.stdin.read(1)   #输出用户输入的内容到屏幕
                    #说明,因为当前终端模式为cblock模式
    
                    if len(x) == 0:
                        break
    
                    if x == '	':     #这里将flag设置为True,具体以上定义flag时有解释
                        flag = True
                    else:
                        temp_list.append(x)   #将用户的输入内容append到一个临时列表中
                    if x == '
    ':    #代表用户输入回车
                        log.write(''.join(temp_list))   #''.join(temp_list)为用户敲的命令,将命令写入到日志文件中
                        log.flush()
                        temp_list.clear()   #清空临时列表
                    chan.send(x)    #发送用户的输入内容到远程主机
    
        finally:
            termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)     #将终端模式还原为最初模式
    
    
    def run():
        """
        让用户输入主机名,用户名并设置默认用户名等
        :return:
        """
        default_username = getpass.getuser()    #获取当前登录用户的用户名
        username = input('Username [%s]: ' % default_username)
        if len(username) == 0:
            username = default_username
    
    
        hostname = input('Hostname: ')
        if len(hostname) == 0:
            print('*** Hostname required.')
            sys.exit(1)
    
        tran = paramiko.Transport((hostname, 22,))       #创建一个连接
        tran.start_client()
    
        default_auth = "p"
        auth = input('Auth by (p)assword or (r)sa key[%s] ' % default_auth)
        if len(auth) == 0:
            auth = default_auth
    
        if auth == 'r':
            default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
            path = input('RSA key [%s]: ' % default_path)
            if len(path) == 0:
                path = default_path
            try:
                key = paramiko.RSAKey.from_private_key_file(path)
            except paramiko.PasswordRequiredException:
                password = getpass.getpass('RSA key password: ')
                key = paramiko.RSAKey.from_private_key_file(path, password)
            tran.auth_publickey(username, key)
        else:
            pw = getpass.getpass('Password for %s@%s: ' % (username, hostname))
            tran.auth_password(username, pw)
    
        # 打开一个通道
        chan = tran.open_session()
        # 获取一个终端
        chan.get_pty()
        # 激活器
        chan.invoke_shell()
    
        posix_shell(chan)
    
        chan.close()
        tran.close()
    
    
    if __name__ == '__main__':
        run()
  • 相关阅读:
    SL复习笔记之平稳转型——基础篇(二、控件和数据访问)
    UML之用例图和类图
    SL复习笔记之平稳转型——基础篇(四、多媒体,工具提示和右键菜单)
    SL复习笔记之平稳转型——基础篇(一)
    SL复习笔记之平稳转型——基础篇(三、SL安装检测和用“刷子”刷出背景)
    平稳转型WP系列之在Windows Phone中谈“委托”、“事件”和“接口”(一、深入理解)
    UML建模之活动图和StarUML使用
    SL复习笔记之平稳转型——基础篇(五、数据绑定)
    使用html parser
    设计模式工厂模式
  • 原文地址:https://www.cnblogs.com/xuanouba/p/5742308.html
Copyright © 2020-2023  润新知