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)

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

posted @ 2021-01-19 21:15  怪味巧克力  阅读(335)  评论(0编辑  收藏  举报