简体   繁体   English

带有Python的灵活UNIX命令行界面

[英]Flexible UNIX command line interface with Python

I was wondering how to create a flexible CLI interface with Python. 我想知道如何使用Python创建灵活的CLI界面。 So far I have come up with the following: 到目前为止,我已经提出了以下建议:

$ cat cat.py
#!/usr/bin/env python

from sys import stdin
from fileinput import input
from argparse import ArgumentParser, FileType

def main(args):

   for line in input():
      print line.strip()

if __name__ == "__main__":
   parser = ArgumentParser()
   parser.add_argument('FILE', nargs='?', type=FileType('r'), default=stdin)
   main(parser.parse_args())

This handles both stdin and file input: 这处理标准输入和文件输入:

$ echo 'stdin test' | ./cat.py
stdin test

$ ./cat.py file
file test

The problem is it doesn't handle multiple input or no input the way I would like: 问题是它不能以我想要的方式处理多个输入或没有输入:

$ ./cat.py file file
usage: cat.py [-h] [FILE]
cat.py: error: unrecognized arguments: file

$ ./cat.py 

For multiple inputs it should cat the file multiple times and for no input input should ideally have same the behaviour as -h : 对于多投入应该cat文件多次并没有输入输入最好有行为为同一-h

$ ./cat.py -h
usage: cat.py [-h] [FILE]

positional arguments:
  FILE

optional arguments:
  -h, --help  show this help message and exit

Any ideas on creating a flexible CLI interface with Python? 关于使用Python创建灵活的CLI界面的任何想法?

Use nargs='*' to allow for 0 or more arguments: 使用nargs='*'允许0个或更多参数:

if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_argument('FILE', nargs='*', type=FileType('r'), default=stdin)
    main(parser.parse_args())

The help output now is: 现在的帮助输出为:

$ bin/python cat.py -h
usage: cat.py [-h] [FILE [FILE ...]]

positional arguments:
  FILE

optional arguments:
  -h, --help  show this help message and exit

and when no arguments are given, stdout is used. 当没有给出参数时,使用stdout

If you want to require at least one FILE argument, use nargs='+' instead, but then the default is ignored, so you may as well drop that: 如果您需要至少一个FILE参数,请改用nargs='+' ,但是默认值将被忽略,因此您最好将其删除:

if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_argument('FILE', nargs='+', type=FileType('r'))
    main(parser.parse_args())

Now not specifying a command-line argument gives: 现在不指定命令行参数将给出:

$ bin/python cat.py
usage: cat.py [-h] FILE [FILE ...]
cat.py: error: too few arguments

You can always specify stdin still by passing in - as an argument: 您始终可以通过传入-作为参数来始终指定stdin

$ echo 'hello world!' | bin/python cat.py -
hello world!

A pretty good CLI interface the handles file input, standard input, no input, file output and inplace editing: 一个非常好的CLI界面,可以处理文件输入,标准输入,无输入,文件输出和就地编辑:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def main(args, help):
    '''
    Simple line numbering program to demonstrate CLI interface
    '''

    if not (select.select([sys.stdin,],[],[],0.0)[0] or args.files):
        help()
        return

    if args.output and args.output != '-':
        sys.stdout = open(args.output, 'w')

    try:
        for i, line in enumerate(fileinput.input(args.files, inplace=args.inplace)):
            print i + 1, line.strip()
    except IOError:
        sys.stderr.write("%s: No such file %s\n" % 
                        (os.path.basename(__file__), fileinput.filename()))

if __name__ == "__main__":
    import os, sys, select, argparse, fileinput
    parser = argparse.ArgumentParser()
    parser.add_argument('files', nargs='*', help='input files')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i', '--inplace', action='store_true', 
                       help='modify files inplace')
    group.add_argument('-o', '--output', 
                       help='output file. The default is stdout')
    main(parser.parse_args(), parser.print_help)

The code simply emulates nl and numbers the lines but should serve as a good skeleton for many applications. 该代码仅模拟nl并对行进行编号,但是对于许多应用程序来说,它应该是一个很好的框架。

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

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