• 简单认识python cmd模块


    0X00 前言

    在早前用别人的工具时,发现有些大佬会用到交互式shell,那时候就挺好奇的,但是一直都没有看一下怎么做到的。

    今天在翻p牛的博客的时候,看到他早之前写的一个工具就有用到交互式shell,看了看源码,发现是用到了一个叫做cmd的模块。

    就想写篇博文记录一下,也好补充一下自己python标签的文章~

    0X01 简介

    cmd模块是python中包含的一个公共模块,用于交互式shell和其它命令解释器等的基类。我们可以基于cmd模块自定义我们的子类,实现我们自己的交互式shell。

    它的执行流程也挺简单的,使用命令行解释器循环读取输入的所有行并解析它们,然后把输入行交给命令处理器来处理。命令行处理器接收并解析输入行,这里先需要知道输入行包括两个部分:命令和参数。通过继承和子类方法重载父类方法的特性,命令行处理器找到适合处理该命令的子类方法。

    比如我们输入的是hello baby,那么我们就重写名为do_hello的函数。倘若处理方法返回True,则直接退出循环。

    简单的代码示例:

     1 from cmd import Cmd
     2 import os
     3 import sys
     4 
     5 class Cli(Cmd):
     6     def __init(self):
     7         Cmd.__init__(self)
     8 
     9     def do_hello(self,line):
    10         print "hello",line
    11 
    12 if __name__ == '__main__':
    13     cli = Cli()
    14     cli.cmdloop()

    输出效果

    0x02 cmd的主要方法和属性

    在认识了cmd模块的主要运行流程,下面就认识一下它的主要函数与及一些我们需要用到的属性。

    方法:

    (1)cmdloop():类似与Tkinter的mainloop,运行Cmd解析器;

    (2)onecmd(str):读取输入,并进行处理,通常不需要重载该函数,而是使用更加具体的do_command来执行特定的命令;

    (3)emptyline():当输入空行时调用该方法;

    (4)default(line):当无法识别输入的command时调用该方法;

    (5)completedefault(text,line,begidx,endidx):如果不存在针对的complete_*()方法,那么会调用该函数,该函数主要是用于tab补充,且只能在linux下使用。

    (6)precmd(line):命令line解析之前被调用该方法;

    (7)postcmd(stop,line):命令line解析之后被调用该方法;

    (8)preloop():cmdloop()运行之前调用该方法;

    (9)postloop():cmdloop()退出之后调用该方法;

    (10)help_command():对command命令的说明,其中command为可变字符

    属性:

    (1)prompt:交互式提示字符,也就是刚才的(Cmd)可以换成我们自己想要的字符

    (2)intro:在进入交互式shell前输出的字符串,可以认定为标志语之类的。其实这个可以在preloop方法输出也是一样的

    下面用一个比较完整的代码来举例:

     1 from cmd import Cmd
     2 import os
     3 import sys
     4 
     5 
     6 
     7 class Client(Cmd):
     8     u"""help
     9     这是doc
    10     """
    11     prompt = 'pyFun>'
    12     intro = 'Welcom to pyFun!'
    13 
    14     def __init(self):
    15         reload(sys)
    16         sys.setdefaultencoding('utf-8')
    17         Cmd.__init__(self)
    18 
    19     def do_hello(self,arg):
    20         print 'hello',arg
    21 
    22     def do_exit(self,arg):
    23         print 'Bye!'
    24         return True #返回True,直接输入exit命令将会退出
    25 
    26     def preloop(self):
    27         print "print this line before entering the loop"
    28 
    29     def postloop(self):
    30         # print 'Bye!'
    31         print "print this line after leaving the loop"
    32 
    33     def precmd(self, line):
    34         print "print this line before do a command"
    35         return Cmd.precmd(self, line)
    36 
    37     def postcmd(self, stop, line):
    38         print "print this line after do a command"
    39         return Cmd.postcmd(self, stop, line)   
    40 
    41 if __name__ == '__main__':
    42     try:
    43         os.system('cls')
    44         client = Client()
    45         client.cmdloop()
    46     except:
    47         exit()

    运行效果:

    0x03 一些情况下的使用

    下面针对一些特定情况进行一些示例

    1,当输入空行的时候,我们可以重载emptyline()来处理:

    def emptyline(self):
        print 'please input command!'

    2,自定义我们自己的交互式提示字符串

    prompt = 'pyFun>'

    3,自定义我们的欢迎语:

    intro = 'Welcom to pyFun!'

    4,使程序能够正常接收ctrl+c的退出方式

    try:
        os.system('cls')
        client = Client()
        client.cmdloop()
    except:
        exit()

    在我按下ctrl+c之后能够正常退出不报错

    5,当输入无法识别的命令时,使用default(line)来处理:

    0x04 总结

    其实模块很简单,大伙理解都不会超过十分钟就明白了,但是要写文章截图,认真去讲清楚才是最费时间的。但这样学到的东西才是最深刻的。

    这篇算是开坑,以后会一直去学习、记录一些python有趣的库。

  • 相关阅读:
    linux grep --我最喜欢的命令~~
    svmrank 的误差惩罚因子c选择 经验
    转:机器学习中的算法(2)-支持向量机(SVM)基础
    转:关于python文件操作大全
    python 求两个时间差
    多个excel合并(excel2007)
    oracle12c 新建表空间
    数据库表被锁了
    join ,left join ,right join有什么区别
    最简洁的权限(菜单)控制
  • 原文地址:https://www.cnblogs.com/r00tuser/p/7515136.html
Copyright © 2020-2023  润新知