zoukankan      html  css  js  c++  java
  • python的sys模块剖析

    python的sys模块剖析

    前言

    由于最近一直在练习编写一些基本的端口扫描工具,虽然很多工具早就已经成熟,我们也不必再造轮子,但是其中的基本原理我们还是要了解和学习一些的,毕竟不能只做“脚本小子”,正如我所认为的一个正确的学习过程应该是这样的:使用—>模仿—>超越。我觉得这也是安全开发所应该经历的过程。从使用别人的工具,到模仿制作相似的工具,再到实现自己独特的想法。所以,学好这些基本模块的使用是很重要的,废话不多说了,直接开始。

    环境

    python——>3.8

    windows

    简要

    sys模块是python自带的模块,无需另外安装,内置了许多函数,我们通过调用这些内置模块函数可以实现很多我们需要的功能,最常见的比如说参数的传递,异常的处理等等。

    sys常用方法文档:

    方法 说明
    sys.argv 接收命令行的参数,是一个列表,第一个元素是文件本身
    sys.exit([arg]) 程序退出,arg表示退出状态,默认为0,arg为0视为成功终止,否则为异常终止
    sys.modules 输出当前程序加载的模块
    sys.path List,指定模块搜索路径,初始化是python的环境变量
    sys.platform 平台操作系统的名称
    sys.stdin 标准输入流
    sys.stdout 标准输出流
    sys.stderr 标准错误流,就是专门用来输出错误的
    sys.exc_info() 给出当前正在处理的异常的信息。返回的信息仅限于当前线程和当前堆栈帧
    sys.exc_clear() 清除当前正在处理的异常的信息

    详细介绍

    下面我们来通过代码实际了解一下,毕竟看文字不如动手敲代码来的实在

    sys.argv

    这个方法是用来传参的,通常我们编写完脚本时候有些形参是需要从外部传入的。

    def demo(p0, p1, p2):
        print('这是自带的第一个参数:', p0)
        print('这是输入的第一个参数:', p1)
        print('这是输入的第二个参数:', p2)
    
    if __name__ == '__main__':
        import sys
        demo(sys.argv[0], sys.argv[1], sys.argv[2])
    

    运行结果:

    >python 1.py First Second
    这是自带的第一个参数: 1.py
    这是输入的第一个参数: First
    这是输入的第二个参数: Second
    

    可见上面要注意输入的第一个参数是从argv[1]开始的

    sys.stdin

    标准输入流,其实已经解释的较为清楚,这个是接收我们输入的,并且是接收一串输入,功能类似input()函数

    def demo(p):
        print('这是接收的输入流:', p)
    
    if __name__ == '__main__':
        import sys
        test = sys.stdin.readline()
        demo(test)
    

    运行结果:

    >python 1.py
    www.jlx-love.com
    这是接收的输入流: www.jlx-love.com
    

    sys.stdin只是接收了我们的键盘输入,但不具备赋值的功能,所以如果想要把输入的值赋值给test,那么我们还需要用到readline,即读取接收的输入流

    sys.stdout

    说完了输入,那我们就紧接着说一说输出,所谓标准输出,即将值输出而已

    def demo():
        sys.stdout.write('www.jlx-love.com')
        sys.stdout = open('out.txt', 'w')
        print('My blog is: www.jlx-love.com')
    
    if __name__ == '__main__':
        import sys
        demo()
    

    简单解释一下,我们可以看到,我demo函数里有两个sys.stdout这是两种用法,第一个就是我们向输出流中写入东西,然后它给输出,功能和print是相似的,不同的是,它只能接收str类型。第二个是什么意思呢?就是说,我把我的输出流送到一个叫out.txt文件,以写的方式打开,然后下面紧接着我输出了一段字符串,那么这段字符串就是输出流,这个输出流就会写到out.txt文件中。这个长用在日志访问输出中。

    运行结果:

    >python 1.py
    www.jlx-love.com
    

    可以看到,我们print输出的内容没有在终端显示,而是直接写到了out.txt文件中

    sys.stderr

    def demo():
        sys.stderr.write('This is a error')
        sys.stderr = open('out.txt', 'w')
        sys.stderr.write('This is a redirect error~')
        
    if __name__ == '__main__':
        import sys
        demo()
    

    跟上一个差不多,这里不再过多阐述,第一个会回显到终端上,第二个则是写到out.txt文件中

    运行结果:

    >python 1.py
    This is a error
    

    sys.path

    def demo():
        print(sys.path)
    
    if __name__ == '__main__':
        import sys
        demo()
    

    运行结果:

    >python 1.py
    ['E:\Python代码', 'D:\Python38\python38.zip', 'D:\Python38\DLLs', 'D:\Python38\lib', 'D:\Python38', 'D:\Python38\lib\site-packages', 'D:\Python38\lib\site-packages\wafw00f-2.1.0-py3.8.egg', 'D:\Python38\lib\site-packa
    ges\pluginbase-1.0.0-py3.8.egg', 'D:\Python38\lib\site-packages\requests-2.23.0-py3.8.egg', 'D:\Python38\lib\site-packages\pysocks-1.7.1-py3.8.egg', 'D:\Python38\lib\site-packages\urllib3-1.25.9-py3.8.egg', 'D:\Python38\
    lib\site-packages\idna-2.9-py3.8.egg', 'D:\Python38\lib\site-packages\chardet-3.0.4-py3.8.egg', 'D:\Python38\lib\site-packages\certifi-2020.4.5.1-py3.8.egg']
    

    输出形式是一个列表,初始化则是python的环境变量,我的python是安装在Dpan,代码写在E盘,我们也可以看到它搜索的顺序,是现在当前目录寻找,然后再去python的环境变量中前去寻找

    sys.exit([argv])

    从名字就知道干啥的啦,退出程序,只不过这个退出也是有不同情况的,有的是正常退出,有的是非正常退出。所以这里就多了一个参数,那么不同参数有什么不同呢?多数系统要求该值的范围是 0--127,否则会产生不确定的结果。某些系统为退出代码约定了特定的含义,但通常尚不完善;Unix 程序通常用 2 表示命令行语法错误,用 1 表示所有其他类型的错误。传入其他类型的对象,如果传入 None 等同于传入 0,如果传入其他对象则将其打印至 stderr,且退出代码为 1。所以我们了解了,不同的参数代表不同的错误类型和退出程序,当然如果是0的话就是正常退出lou,那这个怎么用呢?接下来给大家看看两个不同代码执行结果,来充分理解一下。

    def demo():
        try:
            sys.exit(0)
        except:
            print('www.jlx-love.com')
    
    if __name__ == '__main__':
        import sys
        demo()
    

    运行结果:

    >python 1.py
    www.jlx-love.com
    
    def demo():
            sys.exit(0)
            print('www.jlx-love.com')
    
    if __name__ == '__main__':
        import sys
        demo()
    

    运行结果:

    >python 1.py
    
    

    结果很明显,可以看到第二个什么也没有输出,通过这两个结果的对比,我们可以更深刻的理解一下exit的原理。当调用exit之后,会抛出一个异常,如果这个异常被捕获,则下面的代码会继续执行,反之,若异常没有被捕获,则会直接退出python解释器

    sys.exc_info()

    捕获异常,有时候在某些场景下,只捕获异常是不够的,我们还需要捕获异常的详细信息,那么这个时候exc_info()就排上用场了。这里正好借助上面exit抛出一个异常

    def demo():
        try:
            sys.exit(0)
        except:
            print(sys.exc_info())
    
    if __name__ == '__main__':
        import sys
        demo()
    

    运行结果:

    >python 1.py
    (<class 'SystemExit'>, SystemExit(0), <traceback object at 0x0000014E8C7F4280>)
    

    看到捕获到异常之后,输出了异常的详细信息,这是一个元组,里面有3个元素,第一个元素是一个SystemExit类,第二个元素是SystemExit类的一个实例,第三个元素给出了一个内存地址,但是看不到详细信息,如果想要看到详细信息,就需要使用traceback模块中的print_tb方法

    import traceback
    
    def demo():
        try:
            sys.exit(0)
        except:
            traceback.print_tb(sys.exc_info()[2])
    
    if __name__ == '__main__':
        import sys
        demo()
    

    运行结果:

    >python 1.py
      File "1.py", line 5, in demo
        sys.exit(0)
    

    可以看到输出了文件名,第几行,哪个位置出现了错误,更为详细。

  • 相关阅读:
    centos7 安装高版本svn
    idea 常用快捷键
    IDEA 打可执行jar包(maven项目)
    服务器安装JDK
    阿里云服务器连接AWS-S3
    mysql5.7 修改密码,修改权限
    win10 手动安装mysql-8.0.11-winx64.zip
    centos7 关闭防火墙
    centos7 配置阿里云yum源
    centos7 源码安装nginx
  • 原文地址:https://www.cnblogs.com/Jleixin/p/14300072.html
Copyright © 2011-2022 走看看