• 异常+远程控制Linux-14


    什么是异常

    a=8950/0              ZeroDivisioonError: division by zero

    print (a)

    **************

    b = [1,2]

    c = b[2]              

    print (b+c)             IndexError:List index out of range

    当解释器遇到错误的(无法执行)代码,中断当前代码的执行,抛出一个异常对象

    异常的捕获和处理

    例子:

    输入0会导致当前程序的异常退出

    while True:

      num = input ('input a number:)

      print ('10000 / %s = %s' %(num,10000.0/int(num)))

    捕获一种异常

    关键字 try ...except...

    try :
      b = 4/0

    except  ZeroDivisioonError:

      print ('handle  ZeroDivisioonError‘)

    try 代码块指明作用域,若出现错误try里面的后面的代码不再执行

    except 代码块是异常处理的代码

    捕获多钟类型的错误

    try :

      ohmy

      b = 4/0

    except ZeroDivisioonError:

      print(''handle  ZeroDivisioonError‘)

    except NameError;

      print('handle NameError')

    执行结果:是NameError

     得到异常对象

    捕获后得到详情的异常信息

    try:

      ohmy

    except NameError as e:

      print('handle NameError:',e)

    e就是异常对象

    我们可以打印出里面存储的具体错误信息

    捕获所有异常

    try:

      ohmy

      4/0

    except Exception as e:

      print('handle unkown exception:',e)

    Exception 指明所有异常(父类)

    可简写成

    try:

      ohmy

    except:

      print('handle unkown exception:')

    如果想要知道异常信息

    import traceback    获取异常信息和行号及代码的调用信息,用于日志文件

    try:

      ohmy

    except:

      print('handle unkown exception '+

        traceback.format_exc())

    finally语句

    不管是否有异常,我们都要执行一段代码

    try:

      b = 4/0

      ohmy

    except ZerodivisionError:

      print('handle ZerodivisionError')

    except NameError:

      print('handle NameError')

    except:

      print('handle unkown exception')

    finally:

      print('in finally')

    finally 一定要放在最后,用于环境清除

    else 没有异常的情况下,要执行一段代码

    try:

     print('do something')

    except ZerodivisionError:

      print('handle ZerodivisionError')

    except NameError:

      print('handle NameError')

    except:

      print('handle unkown exception')

    else:

      print('haha, no exception')

    finally:

      print('in finally')

    else 必须跟在所有的except代码块后面

    在finally前面

    函数调用栈

    异常从调用栈里抛出

    远程控制Linux

    经常和Linux打交道:

    产品的运行环境,互联网行业:web server ,Web APP,Mobile APP;通信行业:AAA、BOSS、业务控制...

    经常用到远程操作Linux:自动安装产品到Linux,自动化用例的一些步骤,运维:环境监控,数据的自动获取、分析

    python的解决方案:Paramiko、Pexpect

    安装Paramiko执行下面的命令:

    pip install paramiko --default-timeout=60

    pip install paramiko -i https://pypi.douban.com/simple/

    Linux主机设置:保证有一台Linux主机:自己搭建虚拟机,如果没有临时使用云主机;保证ssh服务开启,用putty连接

    示例代码

    SSHClicent

    import paramiko 

    ssh = paramiko.SSHClient()  #创建SSHClient实例对象

    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())   #调用方法,表示没有存储远程机器的公钥,允许访问

    ssh.connect(hostname,port,user,passwd)                   #连接远程机器,地址、端口(一般为22),用户名,密码

    stdin,stdout,stderr = ssh.exec_command("mkdir abc;touch file1 file2;ls")

    print (stdout.read())

    ssh.close()

    例子

    import paramiko 

    ssh = paramiko.SSHClient()  #创建SSHClient实例对象

    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())   #调用方法,表示没有存储远程机器的公钥,允许访问

    ssh.connect(hostname,port,user,passwd)                   #连接远程机器,地址、端口(一般为22),用户名,密码

    cmd = 'mkdir abc'                               #创建目录

    ssh.exec_command(cmd)

    cmd = ''' echo '1234          #命令跨行

    5678

    90abc' >myfile

    '''

    ssh.exec_command(cmd)

    cmd = 'cat myfile'     #获取命令的执行结果

    stdin,stdout,stderr = ssh.exec_command(cmd)

    print (stdout.read() +stedrr.read())

    ssh.close()

    exec_command 每次执行会新打开一个channel执行,新的环境不在上次执行的环境里面,所以我们不能多次调用,达到多次执行的目的

    可以多个命令一起执行,用分号隔开

    获取数据进行分析

    例如内存使用 date +%Y%m%d_%H%M%S;free

    运输文件到远程机器

    sftp = ssh.open_sftp()

    sftp.put('ftp1.py','/home/stt/ftp3.py')

    sftp.close()

    获取统计 远程Linux主机的 可用内存率。
    
    
    安装 paramiko :  执行pip install paramiko
    
    
    安装虚拟机管理器 virtualbox 或者 vmvareplayer, 创建 64位 虚拟机,
    安装centos镜像
    
    cetos6.9 下载地址 :
    http://mirrors.163.com/centos/6.9/isos/x86_64/CentOS-6.9-x86_64-bin-DVD1.iso
    
    Putty 下载地址 :
    https://the.earth.li/~sgtatham/putty/0.70/w32/putty-0.70-installer.msi
    
        
        
    然后编写一个python程序,代码文件名为 memory.py , 该代码文件 计划在远程Linux机器运行。该程序做如下的事情:
        每隔5秒钟 打开文件 /proc/meminfo,该文件包含了系统内存使用信息,前面数行内容如下
        
    MemTotal:        1920648 kB
    MemFree:           87788 kB
    Buffers:          229704 kB
    Cached:          1180244 kB
    
        memory.py 程序要将 memFree 、buffers、cached 的值 相加 (结果是可用内存的数量)。
        然后除以 MemTotal的值, 得到可用内存占的百分比(赋值给变量 avaMem)。
        将 avaMem 的数值存入 结果文件ret.txt中。
        
        上面的程序一直运行,每隔 5秒钟 获取记录一次 avaMem 对应的时间戳, 格式如下
        20170315_12:10:00  77%
        20170315_12:10:05  74%
        20170315_12:10:10  70%
        20170315_12:10:15  72%
        
        
    
    
    再编写一个python程序,代码文件名为 auto.py,该程序运行起来做如下工作:
        以自己名字的拼音(比如lixia) 在远程机器建立一个目录 。如果该目录已经存在则跳过此步骤
        拷贝文件memory.py 到远程机器该目录下面,
        远程在Linux主机执行文件 memory.py 
        过5分钟后,将远程文件memory.py执行产生的结果文件ret.txt 内容拷贝回本机
    
    

    参考答案,往下翻































    memory.py

    # coding=utf8
    import time
    
    # MemTotal:        1920648 kB
    # MemFree:           87788 kB
    # Buffers:          229704 kB
    # Cached:          1180244 kB
    def getContent(lines,field):
        for line in lines:
            if field in line:
                value = line.split(':')[1].split('kB')[0].strip()
                return int(value)
    
    # count 用来时间上计数,防止一直运行
    count = 0
    while True:
        count += 1
    
        with open('/proc/meminfo') as f:
            beginlines = f.readlines()[:8]
    
        memTotal = getContent(beginlines,'MemTotal')
        memFree  = getContent(beginlines,'MemFree')
        buffers  = getContent(beginlines,'Buffers')
        cached   = getContent(beginlines,'Cached')
    
        # print memTotal,memFree,buffers,cached
        # 别忘了 * 100
        memUsage = (memFree + buffers + cached) *100.0/memTotal
        # 搜索时间格式
        memUsage = '%s     %.2f%%' % (time.strftime('%Y%m%d_%H:%M:%S'),memUsage)
        print(memUsage)
    
        with open('ret.txt','a') as f:
            f.write(memUsage+'
    ')
    
        time.sleep(5)
    
        # 防止一直运行
        if count>15:
            break

    auto.py

    # coding=utf8
    import paramiko,time
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect("120.26.96.231",22,"stt", "stt0707")
    
    
    # 创建自己名字的目录
    dirName =  "jcy"
    
    # 先检查 是否已经存在同名目录了, 如果没有则创建
    stdin, stdout, stderr = ssh.exec_command("ls")
    dircontent =  stdout.read()
    print(dircontent)
    if dirName in dircontent.splitlines():
        print('{} already exists'.format(dirName))
    else:
        print('make dir {}'.format(dirName))
        ssh.exec_command("mkdir {}".format(dirName))
    
    # 传输文件
    sftp = ssh.open_sftp()
    sftp.put('memory.py', '{}/memory.py'.format(dirName))
    sftp.close()
    
    
    # 检查文件是否传输成功,可以将检查文件是否存在机器,做成一个函数。。。
    
    
    # 执行脚本
    
    
    # 考虑到长时间没有消息,网络连接可能会被断开。 到网上搜索一番后。
    # 设置一个保持连接的参数
    transport = ssh.get_transport()
    transport.set_keepalive(30)
    
    print('remote exec python memory.py')
    ssh.exec_command("cd %s; python memory.py" % dirName)
    
    print('wait for 30 seconds...')
    time.sleep(30)
    
    
    # 传输文件
    sftp = ssh.open_sftp()
    sftp.get('{}/ret.txt'.format(dirName),'ret.txt')
    sftp.close()
    
    ssh.close()
  • 相关阅读:
    正则表达式详解<一>
    multimap详讲
    map详讲<二>
    map详解<一>
    priority_queue详解
    容器适配器(一):queue
    用 input() 函数返回的数据是字符串类型
    学习python的基本了解
    学习oracle的SQL语句 练习
    oracle 练习题
  • 原文地址:https://www.cnblogs.com/hyzhang/p/7716224.html
Copyright © 2020-2023  润新知