作者:糖果

无论是用C语言,还是用Java,有时都会写一些命令行的工具,解析用户在命令输入的参数,而Python有自己特色的命令行参数解析库,就是optparse。hpfeed-cli的源码就是用optparse来解析命令行参数的,hpfeed是给威胁地图发送威胁数据的,使用的是hpfeed协议,hpfeed-cli是一个在terminal中直接运行的命令行程序,有着非常复杂的参数输入。

import sys
import optparse
import datetime
import logging
import string


def main(opts, action, pubdata=None):
    outfd = None
    print action
    print data
    print options
    return 0


def opts():
    usage = "usage: %prog -i ident -s secret --host host -p port -c channel1 [-c channel2, ...] <action> [<data>]"
    parser = optparse.OptionParser(usage=usage)

    parser.add_option("-c", "--chan",
    action="append", dest='channels', nargs=1, type='string',
    help="channel (can be used multiple times)")


    parser.add_option("--debug",
    action="store_const", dest='debug',
    help="enable debug log output", default=False, const=True)


    options, args = parser.parse_args()

    if len(args) < 1:
        parser.error('You need to give "subscribe" or "publish" as <action>.')

    if args[0] not in ['subscribe', 'publish', 'sendfile']:
        parser.error('You need to give "subscribe" or "publish" as <action>.')

    if options.debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.CRITICAL)


    action = args[0]
    data = None
    if action == 'publish':
        data = ' '.join(args[1:])
    elif action == 'sendfile':
        data = ' '.join(args[1:])

    return options, action, data


if __name__ == '__main__':
        options, action, data = opts()
        try:
                sys.exit(main(options, action, pubdata=data))
        except KeyboardInterrupt:
                sys.exit(0)

从命令行输入的数据来看, 把数据归为三类:

1.action(动作)
2.data(动作对应的数据)
3.options(动作具体的选项)

以上的action其实是命令行定义的动作,简单说就是执行那种类型的命令,这个命令是命令行的子命令,理论上可以很多,而data就是执行action命令时需要的数据,这数据可以是一个列表。options也可以设置很多个,和option来设置命令执行的方式和区别。

我们根据以上程序的设定来执行一下这个程序,在命令行输入:

python blog-client.py sendfile data_element1 data_element2 data_element3 -c channel --debug

然后,分别看一个 ,action,data,options的值。

sendfile
data_element1 data_element2 data_element3
{'channels': ['channel'], 'debug': True}
action是字符串:sendfile
data是列表:data_element1 data_element2 data_element3
options是map列表:{‘channels’: [‘channel’], ‘debug’: True}

这样我们就将用户命令行输入的参数都解析到适当的数据结构中了,接着要做的就是根据参数定义,执行我们业务逻辑代码。
关于这个库的使用的API,几个:

optparse.OptionParser(usage=usage)
parser.add_option
parser.parse_args
parser.error

这个可以结合代码,领会一下意思吧!