[TOC]

0x00 Python命令行参数

实现命令行参数输入得几种方法:

  • sys模块中的argv
  • getopt 模块中
sys.argv
#!/usr/bin/python
#功能:实现脚本编程cmd参数输入
import sys

#方法1 sys 模块方式#
print('参数个数为',len(sys.argv),'个参数')
print('列表参数列表',str(sys.argv),"\n计算结果:",end="")
add = 0
for value in sys.argv:
if value == sys.argv[0]:
pass
else:
add += int(value)

print(add)

if __name__ == '__main__':
#值得学习之处
try:
argv1 = sys.argv[1]
argv2 = sys.argv[2]
except Exception as e:
print("[*] Error:"+str(e))
sys.exit()

main(sys.argv[1:]) #向main函数传递参数

WeiyiGeek.sys.argv


getopt

Python 提供了 getopt 模块来获取命令行参数(指定参数名称)
getopt 模块是专门处理命令行参数的模块,用于获取命令行选项和参数,也就是sys.argv,命令行选项使得程序的参数更加灵活,支持短选项模式(-)和长选项模式(–)。

语法:

getopt.getopt(args, options[, long_options])  #cmd参数的绑定
getopt.gnu_getopt
getopt.GetoptError #抛出的异常(在没有找到参数列表,或选项的需要的参数为空时会触发该异常)

- args: 要解析的命令行参数列表。
- options: 以字符串的格式定义,options后的冒号(:)表示该选项必须有附加的参数,不带冒号表示该选项不附加参数。
- long_options: 以列表的格式定义,long_options 后的等号(=)表示如果设置该选项,必须有附加的参数,否则就不附加参数。
- 该方法返回值由两个元素组成: 第一个是 (option, value) 元组的列表。 第二个是参数列表包含那些没有'-''--'的参数。

案例:假定我们创建这样一个脚本,可以通过命令行向脚本文件传递两个文件名,同时我们通过另外一个选项查看脚本的使用。

"""
文件命令行参数说明
"""
import sys, getopt
def main(argv):
inputfile = ''
outputfile = ''
try:
opts, args = getopt.getopt(argv,"hi:o:",['help',"ifile=","ofile="]) #注意属性(参数属于绑定的属性), 返回参数一个列表
except getopt.GetoptError:
print ('test.py -i <inputfile> -o <outputfile>')
sys.exit(2)
for opt, arg in opts:
if opt == '-h' or opt == '--help':
print ('test.py -i <inputfile> -o <outputfile>')
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg

print ('输入的文件为:', inputfile) #进行赋值
print ('输出的文件为:', outputfile)

if __name__ == "__main__":
main(sys.argv[1:]) #这也是关键点 (排除脚本文件本身)

WeiyiGeek.getopt


argparse.ArgumentParser

描述:argparse模块用于命令行选项、参数和子命令的解析器

基础语法:

#创建解析器,ArgumentParser对象将保存将命令行转换成Python数据类型所需的所有信息。
parser = argparse.ArgumentParser(description='Process some integers.',prog='TestArgumentDemo')
- prog :程序名称(默认:sys.argv[0])
- usage : 描述程序使用情况的字符串(默认值:生成的fromarguments添加到解析器中)

#定义如何解析单个命令行参数
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
#参数解析:
- name :指定参数名称或选项字符串列表如:'-i','--ip'
- action : 在命令行中遇到此参数时要采取的基本操作类型
- 'store'-它只存储参数的值 Namespace(foo='1')
- 'store_const'-它存储由const参数名称指定的常量值,const=42 Namespace(foo=42)
- 'store_true' and 'store_false' - 是'store_const'的特殊情况,用于分别存储True和false值, Namespace(foo=True, bar=False, baz=True)
- 'append'-它存储一个列表,并将每个参数值附加到列表中。 Namespace(foo=['1', '2'])
- 'append_const'-它存储一个列表,并将每个参数值(常量值)附加到列表中,Namespace(types=[<class 'str'>, <class 'int'>])
- 'count' —计算关键字参数出现的次数。
- version—调用中使用version=关键字参数,并在调用时打印版本信息并退出,action='version', version='%(prog)s 2.0如PROG 2.0 , %(prog)是在ArgumentParser,进行订定义prog='PROG
- nargs : 应该使用的命令行参数的数量(指定参数命令行之后的输入参数个数)
- nargs=2 指定参数后跟定的输入参数个数
- nargs=argparse.REMAINDER 所有剩余的命令行参数都被收集到一个列表中
- const : 一些const和nargs选择所需的常量。
- default : 缺省值
- type : 应将命令行参数转换为的类型,str / int / float
- type=argparse.FileType('r') / type=argparse.FileType('w') 与nargs连用时候是允许可选的输入和输出文件
- dest : 要添加到由parse_args()返回的对象中的属性的名称。
- metavar :使用消息中参数的名称,当ArgumentParser生成帮助消息时,它需要某种方法来引用每个期望的参数。
- 默认情况下,ArgumentParser对象使用destvalue作为每个对象的“名称”。
- 默认情况下,对于位置参数操作,dest值直接使用,对于可选参数操作,dest值大写。
- choices : 选项——参数允许值的容器。
- 应该从一组受限制的值中选择一些命令行参数,choices=['rock', 'paper', 'scissors']),choices=range(1, 4))
- required : 是否可以省略命令行选项(仅限选项/必须还是非必须)。
- True / False
- help :命令参数一个简短的描述

实际案例:

#!/usr/bin/env python
# coding:utf-8
# 功能:了解ArgumentParser与使用

import argparse
import os,sys

def main():
parser = argparse.ArgumentParser(description="""\
实现指定输入参数来来输入的值进行解析
采用Argparse模块中的ArgumentParser方法进行实例化
""",prog='TestArgumentDemo')
parser.add_argument('-i','--ip',dest="ip",type=str,help="""请输入一个IP地址如:192.168.1.1""",required=True)
parser.add_argument('-u','--user',dest="User",type=str,help="指定连接的服务的用户名称",required=True)
parser.add_argument('-p','--pass',dest="Pass",type=str,help="指定连接服务的用户密码",required=True)
parser.add_argument('-P','--port',dest="Port",type=str,help="指定服务的端口默认:25",required=False,default='25')
parser.add_argument('-v','--version',action="version", version='%(prog)s 1.0') #argument.py 1.0
parser.add_argument('-n','--number',dest="Trynum",choices=[1,2,3,4],help="失败重试次数",default=2,type=int) #argument.py 1.0
parser.add_argument('-m','--mutil',dest="Mutil",nargs=2,help="指定2个守护进程PID值",required=True) #nargs=argparse.REMAINDER 多个参数


#位置参数:直接读取文件包或者写入
parser.add_argument('infile',nargs='?',type=argparse.FileType('r'),default=sys.stdin)
parser.add_argument('outfile',nargs='?',type=argparse.FileType('w+'),default=sys.stdout)

#可使用metavar指定替代名称,当ArgumentParser生成帮助消息时,
parser.add_argument('--bar',metavar=['XXX','YYYY']) #它需要某种方法来引用每个期望的参数。
parser.add_argument('demo',metavar=['AAA','bbb']) #位置参数提示

args = parser.parse_args()
print("参数类型:",type(args),"\n参数解析对象:",args)
ip = args.ip
username = args.User
password = args.Pass
port = int(args.Port) #由于参数指定的类型是str所以这里转成int
trynum = args.Trynum #TestArgumentDemo: error: argument -n/--number: invalid choice: 5 (choose from 1, 2, 3, 4)
mutil = args.Mutil
print("IP地址:",ip)
print("用户名:",username)
print("密码:",password)
print("端口:",port)
print("重试次数:",trynum)
print("指定参数名称及多个参数:",mutil)
print("文件读取:",end = " ")
for each in args.infile:
print(each)
print("文件写入:",args.outfile)
print("Matavar期望参数: Bar = ",args.bar," Demo = ",args.demo)
print("版本信息:",end="\t")
os.system('argument.py -v')

if __name__ == '__main__':
main()

执行结果:

$argument.py -h
usage: TestArgumentDemo [-h] -i IP -u USER -p PASS [-P PORT] [-v]
[-n {1,2,3,4}] -m MUTIL MUTIL [--bar ['XXX', 'YYYY']]
[infile] [outfile] ['AAA', 'bbb']

实现指定输入参数来来输入的值进行解析 采用Argparse模块中的ArgumentParser方法进行实例化

positional arguments: 位置参数
infile
outfile
['AAA', 'bbb']

optional arguments: 选项参数
-h, --help show this help message and exit
-i IP, --ip IP 请输入一个IP地址如:192.168.1.1
-u USER, --user USER 指定连接的服务的用户名称
-p PASS, --pass PASS 指定连接服务的用户密码
-P PORT, --port PORT 指定服务的端口默认:25
-v, --version show program's version number and exit
-n {1,2,3,4}, --number {1,2,3,4}
失败重试次数
-m MUTIL MUTIL, --mutil MUTIL MUTIL
指定2个守护进程PID值
--bar ['XXX', 'YYYY']


$argument.py -i 192.168.1.1 -u root -p 123456 -P2222 -m 1024 2048 1.txt 2.txt AAAA --bar YYYY
参数类型: <class 'argparse.Namespace'>
参数解析对象: Namespace(Mutil=['1024', '2048'], Pass='123456', Port='2222', Try
num=2, User='root', bar='YYYY', demo='AAAA', infile=<_io.TextIOWrapper name='1.t
xt' mode='r' encoding='cp936'>, ip='192.168.1.1', outfile=<_io.TextIOWrapper nam
e='2.txt' mode='w+' encoding='cp936'>)
IP地址: 192.168.1.1
用户名: root
密码: 123456
端口: 2222
重试次数: 2
指定参数名称及多个参数: ['1024', '2048']
文件读取: Whoami - 文本内容
文件写入: <_io.TextIOWrapper name='2.txt' mode='w+' encoding='cp936'>
Matavar期望参数: Bar = YYYY Demo = AAAA
版本信息:TestArgumentDemo 1.0