简体   繁体   English

Argparse-不同的必需参数取决于提供的标志

[英]Argparse - different required parameters depnding on flag provided

I wrote a tool in bash that I am trying to convert to python for the sake of expanding my skills beyond beginner but am hitting a snag due to the way I originally formatted the command. 我用bash编写了一个工具,为了将我的技能扩展到初学者之外,我试图将其转换为python,但是由于我最初格式化命令的方式而遇到了麻烦。

The tool restarts a service on a bunch of servers in a cluster that are usually named HOSTNAME01-08 so the original tool takes a hostname, cluster range, service, and action: 该工具在通常称为HOSTNAME01-08的群集中的一堆服务器上重新启动服务,因此原始工具采用主机名,群集范围,服务和操作:

$ prog.sh hostname cluster_range httpd status (ex. of range would be 01-04)

It also has a second function that will do a port check only 它还具有第二个功能,该功能将仅执行端口检查

$ prog.sh -p port_number hostname cluster_range

The second commmand does not require the arguments of service and action. 第二个命令不需要服务和操作的论据。 This is where I am hitting my issue. 这是我要解决的问题。

In converting it to python I am trying to use argparse for all the options and commands as I really like its ability to output clean usage and help information but the second function of the original tool is making this a bit harder. 在将其转换为python时,我尝试将argparse用于所有选项和命令,因为我真的很喜欢它能够输出干净的用法和帮助信息的功能,但是原始工具的第二个功能使此操作变得更加困难。

Using argparse if i set the '-p' flag that works fine and all, but its still requring the last two arguments that are not needed or it fails with "too few arguments" 如果我将argparse设置为可以正常运行的'-p'标志,则使用argparse,但是它仍然需要最后两个不需要的参数,否则会因“参数太少”而失败

I thought maybe subparsers would be the way to go, but subparsers don't seem to work with flag style names (think i read somewhere it strips it?). 我以为可能会使用次级解析器,但是次级解析器似乎无法使用标志样式名称(想想我读过的地方会剥离它吗?)。 The other issue is if I create the subparser for '-p' even with a proper name (say portcheck) it will only work if I create a subparser for the other task as well (call it main-task), it wont accept having base arguments for the main parser and separate arguments for just the subparser. 另一个问题是,即使我使用正确的名称为“ -p”创建了子解析器(例如,portcheck),它也只能在我为其他任务(也称为主任务)创建子解析器的情况下起作用,它不会接受具有主解析器的基本参数和子解析器的单独参数。 So i would be forced to use commands like 所以我将被迫使用类似的命令

$ prog.py  main-task  hostname  range  service  action
$ prog.py  portcheck  port_num  hostname  range

Is there a way to use the optional '-p' flag and trigger it to not need the other two arguments? 有没有办法使用可选的'-p'标志并触发它不需要其他两个参数? The best solution I can think of is to check for the -p flag and if true to set those two variables to empty strings, is it possible to adjust those arg values in an if statement? 我能想到的最佳解决方案是检查-p标志,如果将这两个变量设置为空字符串为true,是否可以在if语句中调整这些arg值? I could set those two arguments to default as empty to start with but then I couldn't error check if they don't provide all the arguments for the base function defeating the purpose of argparse. 我可以将这两个参数默认设置为空,但是我不能错误检查它们是否没有提供基本参数的所有参数,从而破坏了argparse的目的。 I originally started using sys.argv but was thinking argparse would be more pythonic and a good lesson to try as a beginner. 我最初开始使用sys.argv,但当时认为argparse会更具有Python风格,并且是一个适合初学者的好课程。 Perhaps sys.argv may be the best way to go? 也许sys.argv可能是最好的选择?

argparse code I currently have: 我目前拥有的argparse代码:

parser = argparse.ArgumentParser(
    usage=None,
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description=textwrap.dedent('''\
    Usage:
    drtt BASE-HOSTNAME  CLS-RANGE  SERVICE  ACTION
    ex. drtt HOSTNAME 01-08 sshd status

    For port check only:
    drtt [-p, --port-number] PORT-NUMBER  BASE-HOSTNAME  CLS-RANGE
    ex. drtt -p 1234 HOSTNAME 01-08'''))

parser.add_argument('base_hostname', help='Host name only')
parser.add_argument('--port-number', '-p', type=int, metavar='PORT-NUMBER', help="Port number to check if listening")
parser.add_argument('cls_range', help='Number of hosts in cluster (written as start-finish ex. 01-16)')
parser.add_argument('service', help='Service/Process to perform an action on')
parser.add_argument('action', help='start, stop status or restart')
args = parser.parse_args()

Sorry for the wordy post 对不起罗post的帖子

You can set the nargs of the last two arguments to '?' 您可以将最后两个参数的nargs设置为'?' (0 or 1) and manually check that they are both present if -p is not: (0或1),并手动检查它们是否同时存在(如果-p不存在):

if args.port_number is None and (args.service is None or args.action is None):
    parser.print_help()
    parser.error("Missing mandatory arguments sevice and action")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM