Python
optparse
# Python
from optparse import OptionParser
usage = "here is help messages of the command line tool."
opt_parser = OptionParser(usage)
opt_parser.add_option('-s', '--switch', action='store_false', help='set options as switch')
opt_parser.add_option('-n', '--name', type='string', dest='nickname', help='pass in single name')
opt_parser.add_option("-f", "--filename", metavar="FILE", help="write output to FILE")
test_args = ['-n', 'looking', '-s', '-f', 'outfile.txt']
# python test.py -n looking -s -f outfile.txt
(options, args) = opt_parser.parse_args(test_args)
print(opt_parser.print_help())
print(options)
[root@master python3_learning]# python3 test.py
Usage: here is help messages of the command line tool.
Options:
-h, --help show this help message and exit
-s, --switch set options as switch
-n NICKNAME, --name=NICKNAME
pass in single name
-f FILE, --filename=FILE
write output to FILE
None
{'switch': False, 'nickname': 'looking', 'filename': 'outfile.txt'}
1. add_option 选项里的 -arg1 和 --arg2 一般是对应的,而且默认会把解析的结果保存到 args2 里边,比如下面例子中的 -f 选项:
opt_parser.add_option("-f", "--filename", metavar="FILE", help="write output to FILE")
最终会以 filename 来保存对应的解析结果:
{..., 'filename': 'outfile.txt'}
2. 除非你自己指定了具体的 dest='args3',那么它会以 args3 为变量名保存。比如下面例子的 -n 选项:
opt_parser.add_option('-n', '--name', type='string', dest='nickname', help='pass in single name')
最终会以 nickname (而不是 name)来保存对应的解析结果(如果没有 dest='nickname' 选项,则结果会包含 ‘name': 'looking'):
{..., 'nickname': 'looking', ...}
3. action='store_true' (action='store_false' )表示用户不需给出参数值,该类型定义了将布尔值 true (false) 保存到 dest 指定的变量中,比如下面例子的 -s 选项:
opt_parser.add_option('-s', '--switch', action='store_false', help='set options as switch')
解析 -s 的结果是(如果选项里没有 -s, 则结果为 'switch': None):
{'switch': False, ...}
4. add_option 选项里的 default 参数用于设置默认值:
opt_parser.add_option("-u", "--user", default="root", help="set user to login")
如果参数里边没有指定 -u 的值,则解析结果会使用默认的值:
{..., 'user': 'root'}
argparse
据说 argparse 要比 optparse 更强大一些哟。下面例子展示的是多个子解析器的使用方式,细节就不用我多讲啦。
# python
# command.py
import argparse
def run_scan(args):
print('run_scan', args.p, args.l)
def run_aparser(args):
print('run_aparser', args.p)
class Command:
def __init__(self):
self.parser = argparse.ArgumentParser(description='x2openEuler tool chain')
self.subparser = self.parser.add_subparsers(description='subcommand parser')
self.scan_parser = self.subparser.add_parser('scan', help='Migration assessment tool')
self.aparser = self.subparser.add_parser('collect-conf-info', help='aparser tool')
self.add_args()
self.set_func()
def add_args(self):
self.parser.add_argument('-v', '--version', action='version', version='0.1.0 beta', help='Display version')
# add_argument 中参数不加 - 的话表示位置参数,
self.scan_parser.add_argument('p', help='Specify the path of scan')
self.scan_parser.add_argument('-l', choices=['auto', 'c', 'python', 'java'], help='Select the language of scan')
self.aparser.add_argument('p', help='Specify the path of file_dir')
def set_func(self):
# python3 command.py scan /root/lukaiyi/ttt/python3-pandas-0.25.3-1.oe1.aarch64.rpm -l python
self.scan_parser.set_defaults(func=run_scan)
# python3 command.py collect-conf-info /root/lukaiyi/ttt/test
self.aparser.set_defaults(func=run_aparser)
def exec_func(self):
args = self.parser.parse_args()
args.func(args)
if __name__ == '__main__':
Command().exec_func()
后来发现,这个 nargs 真的是太好用啦(其他的目前倒还没仔细研究过),它竟然能够给位置参数设置默认值(很屌的,有点颠覆了我的认知,我原先以为就可选参数是可以设置默认值的)。
没设置 nargs 的时候是这样子:
from argparse import ArgumentParser
parser = ArgumentParser(description='Test')
parser.add_argument("command", help="the command to be executed",
choices=["dump", "delete", "update", "set"], default="set")
args = parser.parse_args()
print(args.command)
C:\Users\lukaiyi\insight-tool>python test.py delete
delete
C:\Users\lukaiyi\insight-tool>python test.py
usage: test.py [-h] {dump,delete,update,set}
test.py: error: the following arguments are required: command
我本来想的是如果位置参数没写的话,会给我把默认值 set 返回来,结果偏偏不给我面子。
但是加上 nargs='?' 就不一样啦(这个时候位置参数就算没写,也可以直接使用给定的默认值):
nargs='?'
from argparse import ArgumentParser
parser = ArgumentParser(description='Test')
parser.add_argument("command", help="the command to be executed",
choices=["dump", "delete", "update", "set"], nargs='?', default="set")
args = parser.parse_args()
print(args.command)
C:\Users\lukaiyi\insight-tool>python test.py
set
C:\Users\lukaiyi\insight-tool>python test.py delete
delete
C:\Users\lukaiyi\insight-tool>python test.py delete update
usage: test.py [-h] [{dump,delete,update,set}]
test.py: error: unrecognized arguments: update
也有使用 nargs='*' 和 nargs='+' 的,看起来和正则表达式中的 ? * + 比较像(实际上含义也确实比较像)。
nargs='?' 表示这个位置参数可设置零个或一个;nargs='*' 表示这个位置参数可设置零个或多个;nargs='+' 表示这个位置参数可设置一个或多个。如果还是不清楚的话可以看看下面的例子。
nargs='*'
from argparse import ArgumentParser
parser = ArgumentParser(description='Test')
parser.add_argument("command", help="the command to be executed",
choices=["dump", "delete", "update", "set"], nargs='*', default="set")
args = parser.parse_args()
print(args.command)
C:\Users\lukaiyi\insight-tool>python test.py
set
C:\Users\lukaiyi\insight-tool>python test.py delete
['delete']
C:\Users\lukaiyi\insight-tool>python test.py delete update
['delete', 'update']
nargs='+'
from argparse import ArgumentParser
parser = ArgumentParser(description='Test')
parser.add_argument("command", help="the command to be executed",
choices=["dump", "delete", "update", "set"], nargs='+', default="set")
args = parser.parse_args()
print(args.command)
C:\Users\lukaiyi\insight-tool>python test.py
usage: test.py [-h] {dump,delete,update,set} [{dump,delete,update,set} ...]
test.py: error: the following arguments are required: command
C:\Users\lukaiyi\insight-tool>python test.py delete
['delete']
C:\Users\lukaiyi\insight-tool>python test.py delete update
['delete', 'update']
Ruby
ruby 的解析就更简单了,一看便懂,就更不用多说了。
# Ruby
require 'optparse'
options = {}
opt_parser = OptionParser.new do |opts|
opts.banner = 'here is help messages of the command line tool.'
opts.separator ''
opts.separator 'Specific options:'
opts.separator ''
options[:switch] = false
opts.on('-s', '--switch', 'Set options as switch') do
options[:switch] = true
end
opts.on('-n NAME', '--name Name', 'Pass-in single name') do |value|
options[:name] = value
end
opts.on('-a A,B', '--array A,B', Array, 'List of arguments') do |value|
options[:array] = value
end
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit
end
end
opt_parser.parse!(ARGV)
puts options.inspect
[root@master ruby_learning]# ./test.rb -h
here is help messages of the command line tool.
Specific options:
-s, --switch Set options as switch
-n, --name Name Pass-in single name
-a, --array A,B List of arguments
-h, --help Show this message
[root@master ruby_learning]# ./test.rb -a hello,world
{:switch=>false, :array=>["hello", "world"]}
[root@master ruby_learning]# ./test.rb -s -a hello,world
{:switch=>true, :array=>["hello", "world"]}
[root@master ruby_learning]# ./test.rb -s -n looking -a hello,world
{:switch=>true, :name=>"looking", :array=>["hello", "world"]}