python 命令列引數sys.grgv和getopt模組
在執行程式時,可能需要根據不同的條件,輸入不同的命令列選項來實現不同的功能。
目前有短選項和長選項兩種格式。短選項格式為"-"加上單個字母選項;長選項為"--"加上一個單詞。
命令列引數分為選項(opts)和引數(args)
sys.argv獲得命令列引數
import sys
print(sys.argv)
執行程式
D:\projects\runcmd>python test.py -a -b args1 --cc --dd=args2 file1
['test.py', '-a', '-b', 'args1', '--cc', '--dd=args2', 'file1']
可見,所有命令列引數以空格為分隔符,都儲存在了sys.argv列表中。其中第1個為指令碼的檔名。
選項的寫法要求
短格式
"-"號後面要緊跟一個選項字母。
如果還有此選項的附加引數,可以用空格分開,也可以不分開。長度任意,可以用引號。
-o #只有選項,沒有引數,用作功能開關
-oa #選項加引數,沒有空格
-obbbb #選項加引數,沒有空格
-o bbbb #選項加引數,有空格
-o "a b" #選項加引數,引數有空格需要加引號
長格式
"--"號後面要跟一個單詞。
如果還有此選項的附加引數,後面要緊跟"=",再加上引數。"="號前後不能有空格。
--help=file1
getopt分析命令列引數
由sys.argv獲得命令列引數以後,使用getopt模組進行分析
語法
getopt(args, shortopts, longopts=[])
第一個引數args為要分析的引數列表,一般設定為sys.argv[1:]
第二個引數為短格式選項
- 當只有選項,沒有引數時,即-h 樣式,在分析串中寫入該字元,h或者-h
- 當選項有引數時,即-f file1樣式,在分析串中寫入該字元加冒號,f:或者-f:
第三個引數為長格式選項
當只有選項,沒有引數時,即--help樣式,在分析串中寫入該引數。help
當選項有引數時,即--file=file1時,在分析串中吸入該引數加等號。file=
返回值
opts, args兩個列表
opts為分析出的格式資訊。opts是一個兩元組的列表。每個元素為:(選項串,附加引數)。如果沒有附加引數則為空字串。
args為不屬於格式資訊的剩餘的命令列引數,即不是按照getopt()裡面定義的長或短選項字元和附加引數以外的資訊。
示例1:getopt分析指令碼引數
程式碼:
import sys,getopt
print(sys.argv)
opts, args = getopt.getopt(sys.argv[1:], '-a-b:', ['cc', 'dd='])
print('opts',opts)
print('args',args)
執行:
D:\projects\runcmd>python test.py -a -b args1 --cc --dd=args2 file1
['test.py', '-a', '-b', 'args1', '--cc', '--dd=args2', 'file1']
opts [('-a', ''), ('-b', 'args1'), ('--cc', ''), ('--dd', 'args2')]
args ['file1']
示例2:getopt進一步分析指令碼引數,進行下一步處理
程式碼:
import sys,getopt
print(sys.argv)
opts, args = getopt.getopt(sys.argv[1:], 'hi:', ['help', 'ip='])
print('opts',opts)
print('args',args)
for opt_name,opt_value in opts:
if opt_name in ['-h','--help']:
print('help doc')
sys.exit()
if opt_name in ['-i','--ip']:
print(opt_value)
sys.exit()
執行:
D:\projects\runcmd>python test.py -h
['test.py', '-h']
opts [('-h', '')]
args []
help doc
D:\projects\runcmd>python test.py -i 192.168.1.1
['test.py', '-i', '192.168.1.1']
opts [('-i', '192.168.1.1')]
args []
192.168.1.1
示例3:各種用法
直接執行指令碼,不加選項和引數,顯示幫助資訊
if len(sys.argv[1:]) == 0:
print(helpdoc)
sys.exit()
執行指令碼,加-h或者--help選項,顯示幫助資訊
opts, args = getopt.getopt(sys.argv[1:], 'hsf:')
argsdict = {}
for opt_name, opt_value in opts:
argsdict[opt_name]=opt_value
if '-h' in argsdict: #幫助資訊
print(helpdoc)
sys.exit()
引數資訊不足,顯示幫助資訊
opts, args = getopt.getopt(sys.argv[1:], 'hsf:')
if len(args) < 5: # file,port,username,passeord,command1,[command2]...
print(helpdoc)
sys.exit()
獲取引數資訊
opts, args = getopt.getopt(sys.argv[1:], 'hsf:')
file, port, username, password, *commands = args
選項列表轉化為字典
opts, args = getopt.getopt(sys.argv[1:], 'hsf:')
for opt_name, opt_value in opts:
argsdict[opt_name]=opt_value
選項資訊不足,提示缺少選項
ip,port = None,None
for opt_name,opt_value in opts:
if opt_name in ['-h', '--help']:
print('help doc')
sys.exit()
if opt_name in ['-i', '--ip']: ip = opt_value
if opt_name in ['--port']: port = opt_value
if not ip:
print('ip not exit')
sys.exit()
if not port:
print('port not exit')
sys.exit()
處理選項與引數
處理選項
- 可以將選項列表轉化為字典,然後判斷選項是否在字典中
帶引數的選項使用vaule = dict.get(key),
如果存在則返回引數值,如果不存在引數值為None,也可以dict.get(key,default)指定預設引數值
不帶引數的選項使用in判斷
- 可以直接處理(選項,引數)元組組成的列表,迴圈處理
為了防止執行指令碼時,提交選項不足,使得引數未獲取到值,可以先賦值變數值為空字串或None,
然後再判斷變數值,如果為空字串或者None,中斷程式,提示引數不足
處理引數
引數被收集到args列表中,是順序的,所以針對列表
- len()判斷引數個數
- 如果不需要進一步處理,直接傳參列表args,或者列表解包*args
- 如果需要進一步處理,列表解包,file, port, username, password, *commands = args,再傳參
- 函式fun形參為arge形式,表示只接受一個引數,呼叫時傳入列表,fun(commands)
- 函式fun形參為*arge形式,表示接受多個引數,呼叫時傳入解包列表,fun(*command)
示例4:模板
程式碼:
import sys,getopt
def fun(ip,port,args):
if flag :
print('True',ip,port,args)
else:
print('false',ip,port,args)
#不加引數提示幫助資訊,或者執行函式
if len(sys.argv[1:]) == 0:
print('help doc')
sys.exit()
try: #getopt函式放到try裡面,防止指令碼呼叫時,出現不期望的引數,會報錯
opts, args = getopt.getopt(sys.argv[1:], 'hsi:', ['help','ip=','port='])
except Exception as e:
print(e)
sys.exit()
#先分析選項
ip,port = None,None #提前賦值變數,然後分析getopt的返回結果,再對變數值進行判斷,適用於必須的選項
flag = False #標誌位,先置於False,再分析getopt的返回結果,如果存在標誌位,再置為True,再在函式中判斷標誌位,作出不同的響應
for opt_name,opt_value in opts:
if opt_name in ['-h', '--help']: #幫助資訊
print('help doc')
sys.exit()
if opt_name in ['-i', '--ip']: ip = opt_value #必須引數
if opt_name in ['--port']: port = opt_value #必須引數
if opt_name in ['-s']:flag = True #功能性引數,標誌位
#
if not ip:
print('ip not exit')
sys.exit()
if not port:
print('port not exit')
sys.exit()
#再分析引數
if len(args) < 1: # 判斷引數個數
print('helpdoc')
sys.exit()
else:
fun(ip,port,args) #如果選項都存在且不為空字串,引數個數也齊全,再執行函式
執行:
D:\projects\runcmd>python test.py -i 192.168.0.1 --port=22 file1
false 192.168.0.1 22 ['file1']
D:\projects\runcmd>python test.py -s -i 192.168.0.1 --port=22 file1
True 192.168.0.1 22 ['file1']
D:\projects\runcmd>python test.py -i 192.168.0.1 --port=22 file1 file2
false 192.168.0.1 22 ['file1', 'file2']
D:\projects\runcmd>python test.py -s -i 192.168.0.1 --port=22 file1 file2
True 192.168.0.1 22 ['file1', 'file2']