argparse模块种命令行框架,经常敲这样的命令

例如nmap -p 80 xxxxxxx

argparse模块的构成

1
2
3
4
import argparse                          #导入argparse模块
parser = argparse.ArgumentParser() #创建一个解析的对象
parser.add_argument()                     #添加参数
parser.parse_args()                       #获取参数

演示

代码

1
2
3
4
5
import argparse
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-p',help='添加参数说明')
args=parse.parse_args()
print(args.p)

终端运行python3 xxxx.py -p abc结果

1
abc

终端运行python3 xxxx.py --help结果

1
2
3
4
5
6
7
usage: cs.py [-h] [-p P]

命令行帮助的开始文字

optional arguments:
-h, --help show this help message and exit
-p P 添加参数说明

ArgumentParser的参数

参数 作用
description 命令行帮助的开始文字,大部分情况下,我们只会用到这个参数
epilog 命令行帮助的结尾文字
prog 程序的名字
prefix_chars 命令的前缀,默认是-
fromfile_prefix_chars 当需要从文件中读取其他参数时
add_help 为解析器添加一个 -h/–help 选项,默认值: True
parents 一个 ArgumentParser 对象的列表,它们的参数也应包含在内
argument_default 参数的全局默认值,默认None
usage 描述程序用途的字符串(默认值:从添加到解析器的参数生成)
conflict_handler 解决冲突选项的策略(通常是不必要的)

源代码的参数,这个是我从源代码里面复制出来的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def __init__(self,
prog=None,
usage=None,
description=None,
epilog=None,
parents=[],
formatter_class=HelpFormatter,
prefix_chars='-',
fromfile_prefix_chars=None,
argument_default=None,
conflict_handler='error',
add_help=True,
allow_abbrev=True,
exit_on_error=True):

description参数

1
2
3
4
5
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-p',help='添加参数说明') #添加参数
args=parse.parse_args()  #获取参数
print(args.p)

终端运行python3 xxxx.py --help结果

1
2
3
4
5
6
7
usage: cs.py [-h] [-p P]

命令行帮助的开始文字

optional arguments:
-h, --help show this help message and exit
-p P 添加参数说明

add_argument的参数

参数 作用
参数 第一个是设置参数的比如parse.add_argument('-p')
可选的选项 可选的选项,比如parse.add_argument('-f','–file')
type 命令行参数应当被转换成的类型,简单来说就是指定参数的类型比如int类型
choices 设置参数值的范围,比如parse.add_argument(‘-p’, choices=[‘a’, ‘b’, ‘d’])
required 是否必须使用这个参数,比如sqlmap必须用-u添加目标
help 参数的说明,可以用-h/–help看到
metavar 参数的值说明
dest 属性命名,默认好像是参数名就是属性名
default 默认值
action 如果使用了这个参数,他的值比较多
const 常用于命令行中不带参数的选项

参数和可选的选项

就是比如下面的代码

1
parse.add_argument('-f','–file')# -f和–file是一样的

choices参数

代码

1
2
3
4
5
import argparse 
parse=argparse.ArgumentParser()
parse.add_argument('-p', choices=['a', 'b', 'd']) # 指定-p只能使用a和b和d参数
args=parse.parse_args()
print(args.p)

结果

1
2
3
4
5
zss >>> python3 cs.py -p f    # 第一次
usage: cs.py [-h] [-p {a,b,d}]
cs.py: error: argument -p: invalid choice: 'f' (choose from 'a', 'b', 'd')
zss >>> python3 cs.py -p a # 第二次
a

required

是否必须使用这个参数,比如sqlmap必须用-u添加目标

代码

1
2
3
4
5
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-u',help='添加参数说明',required=True) #添加参数
args=parse.parse_args() #获取参数
print(args.p)

结果

1
2
3
>>> python3 cs.py              
usage: cs.py [-h] -u U
cs.py: error: the following arguments are required: -u

metavar

参数的值说明

代码

1
2
3
4
5
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-u',help='添加参数说明',metavar='目标URL') #添加参数
args=parse.parse_args() #获取参数
print(args.p)

结果

1
2
3
4
5
6
7
8
>>> python3 cs.py  -h
usage: cs.py [-h] [-u 目标URL]

命令行帮助的开始文字

optional arguments:
-h, --help show this help message and exit
-u 目标URL 添加参数说明

dest

属性命名,默认好像是参数名就是属性名

代码

1
2
3
4
5
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-u',help='添加参数说明',dest='abc') #添加参数
args=parse.parse_args() #获取参数
print(args.abc) # 输出用dest参数定义的abc

结果

1
2
>>> python3 cs.py -u aaa
aaa

default

参数未在命令行中出现时使用的值

代码

1
2
3
4
5
6
7
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')
parse.add_argument('-u',help='添加参数说明',default='aaaaa') #添加参数
parse.add_argument('-p',help='添加参数说明') #添加参数
args=parse.parse_args() #获取参数
print(args.u)
print(args.p)

结果

1
2
3
>>>  python3 cs.py -p bbbb
aaaaa
bbbb

action

关键字action只支持以下值,我们稍后再详细讲解每一个值的含义:

含义
store 保存参数值
store_const 关键字const配合使用,保存关键字const的值
store_true 保存值为True
store_false 保存值为False
append 保存多次选项值为列表
append_const 关键字const配合使用,保存关键字const的值为列表
const 保存选项的出现次数
help 效果等效于-h--help
version 打印版本

store

保存参数值,这也是默认的行为,我们看个例子:

1
2
3
4
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')

parse_args()之后,--foo选项的值就保存到了parse_args()的解析结果对象中。

我们可以这样获取解析结果对象的值:

1
2
Copyargs = parser.parse_args('--foo 1'.split())
print(args.foo)

总结来说,选项名成为了解析结果对象的成员,而选项对应的值则成了成员的值

到这里,我们存在2个疑惑:

  1. 当同时支持-f--foo时,生成的成员名是什么呢?能自定义名字么?
  2. PROG -f这样不需要带参数的选项,存储的成员值是什么样的呢?

不用急,我们继续往下看

store_const

在匹配到选项后,存储关键字const的值,常用于命令行中不带参数的选项。例如:

1
2
3
4
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)

从上面的例子,我们可以看到,在匹配到--foo后,对应成员foo的保存为了const参数的值。

但更多时候,我们不带参数的选项更多只是表示布尔型的开关,这时候我们可用store_true或者store_false

store_true 和 store_false

store_truestore_false是一种特殊的store_const,存储的值类型为布尔型TrueFalse。例如:

1
2
3
4
5
6
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)

示例中有3个布尔型“开关”,可以发现有以下特点:

  1. store_true在匹配到命令选项后,保存为True;相对的,store_false保存为False
  2. 当命令行中没匹配到开关后,例如示例中的baz,则保存为store_false的相反值True

append

把所有值保存为一个列表,常用于支持多次选项的情况,例如:

1
2
3
4
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])

append_const

store_const非常相似,只是把值存储为一个列表。此时如果没有指定关键字const,则默认为Noneappend_const常用于多个不同选项值需要存储到相同成员列表的情况。例如:

1
2
3
4
5
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])

理解上文需要知道以下前提:

  1. 关键字dest用于指定成员名
  2. 参数的值可以是各种对象,包括类型对象,即示例中的str类型int类型

在示例中,--str的常量值是*str类型*,以列表形式保存到types成员*--int的常量值是int类型*,以列表形式保存到types成员**

count

如果我们只需要统计选项出现的次数,此处可以用count,例如:

1
2
3
4
Copy>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count')
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)

help

打印帮助信息,功能等效于-h|--help

version

打印版本信息,需要配合关键字version使用,例如:

1
2
3
4
5
Copy>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0

add_argument_group(参数组)

许多程序将拆分为多个参数组,详细使用查看https://docs.python.org/3/library/argparse.html#argument-groups代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
import argparse #导入argparse模块
parse=argparse.ArgumentParser(description='命令行帮助的开始文字')

a=parse.add_argument_group("目标扫描", "下面是目标扫描参数") # 子选项
a.add_argument('-p', help='目标端口',metavar='端口') #添加参数
a.add_argument('-url', help='目标地址',metavar='ip') #添加参数

b=parse.add_argument_group("信息收集", "下面是信息收集参数") # 子选项

b.add_argument('-x', help='撒旦信息收集',metavar='xxx') #添加参数
b.add_argument('-f', help='fofa信息收集',metavar='xxx') #添加参数

args=parse.parse_args() #获取参数

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> python3 cs.py -h
usage: cs.py [-h] [-p 端口] [-url ip] [-x xxx] [-f xxx]

命令行帮助的开始文字

optional arguments:
-h, --help show this help message and exit
目标扫描:
下面是目标扫描参数
-p 端口 目标端口
-url ip 目标地址

信息收集:
下面是信息收集参数
-x xxx 撒旦信息收集
-f xxx fofa信息收集