如何不退出点击CLI?

时间:2018-10-10 12:28:04

标签: python python-3.x command-line-interface

我正在编写一个python脚本,该脚本的行为应类似于典型的shell,并提供一些自行编写的功能。 它已经运行良好,但是在成功执行命令后它始终会退出,因此必须再次启动它才能执行第二项任务。 我该怎么做,使其不能以退出代码0结束,而是返回到shell等待新的输入?那我将如何实现退出方法? 以下示例始终在键入print-a或print-b后退出:

import click
import click_repl
from prompt_toolkit.history import FileHistory
import os

@click.group(invoke_without_command=True)
@click.pass_context
def cli(ctx):
     if ctx.invoked_subcommand is None:
         ctx.invoke(repl)

@cli.command()
def print_a():
    print("a")


@cli.command()
def print_b():
    print("b")


@cli.command()
def repl():
    prompt_kwargs = {
        'history': FileHistory(os.path.expanduser('~/.repl_history'))
    }
    click_repl.repl(click.get_current_context(), prompt_kwargs)

def main():
    while True:
        cli(obj={})


if __name__ == "__main__":
    main()

(还有一个额外的问题:在cmd程序包中,可以自定义>提示标签,单击可以吗?所以它类似于App>?)

3 个答案:

答案 0 :(得分:1)

使用standalone_mode参数,请尝试以下操作:

rv = cli(obj={}, standalone_mode=False)

解析失败时,上面的代码将引发UsageError。传递--help时,rv将是整数0。在大多数其他情况下,返回处理该命令的函数的返回值,尽管有很多异常,并且一般情况下行为很复杂,在这里有更多说明: https://click.palletsprojects.com/en/master/commands/#command-return-values

此方法的优点是您可以使用命令处理程序中的返回值。缺点是当解析失败(也许有办法还原它)时,您会丢失漂亮的打印帮助消息。


另一种选择是不使用standalone_mode,而是将对cli的调用包装在try/except块中,在其中捕获SystemExit

try:
    cli(obj={})
except SystemExit as e:
    if e.code != 0:
        raise

通过捕获SystemExit,您可以停止通过单击启动的程序退出过程。如果命令成功解析,则捕获SystemExit(0)。再次注意,解析--help也算作“成功”解析,因此也返回SystemExit(0)

此方法的缺点是您不能使用命令处理程序的返回值,这使得更难知道何时传递--help。这样做的好处是可以还原到控制台的所有帮助消息。

我还应该注意,SystemExit继承自BaseException,而不继承自Exception。因此,要实际捕获SystemExit,您可以直接捕获它,也可以捕获BaseException

答案 1 :(得分:0)

只需将所有代码放入while循环内

def main():
    # your code

while True:
    main()

您可以使用Ctrl+C键盘命令退出python脚本

答案 2 :(得分:0)

您可以签出click-shell,它是click和python cmd模块的包装。它支持自动完成和开箱即用的文档字符串帮助。