wim*_*wim 34 python bash command-line-interface tab-completion argparse
如何argparse在Python脚本中使用shell选项卡完成协作?
#!/usr/bin/env python
import argparse
def main(**args):
pass
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('positional', choices=['spam', 'eggs'])
parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
args = parser.parse_args()
main(**vars(args))
Run Code Online (Sandbox Code Playgroud)
在.py文件上设置可执行标志后,预期结果应为:
$ ./example.py sp<tab>
-> completes to "./example.py spam"
$ ./example.py --op<tab>
-> completes to "./example.py --optional"
$ ./example.py --optional b<tab>
-> completes to "./example.py --optional bar"
$ ./example.py --optional f<tab>
-> completes to "./example.py --optional foo"
and, additionally, prints "foo1 foo2" choices on stdout on a new line
Run Code Online (Sandbox Code Playgroud)
Ant*_*hon 49
看看argcomplete由安德烈Kislyuk.
安装它:
pip install argcomplete
Run Code Online (Sandbox Code Playgroud)
在调用之前导入模块并在源代码中添加一行parser.parse_args():
#!/usr/bin/env python
import argparse as ap
import argcomplete
def main(**args):
pass
if __name__ == '__main__':
parser = ap.ArgumentParser()
parser.add_argument('positional', choices=['spam', 'eggs'])
parser.add_argument('--optional', choices=['foo1', 'foo2', 'bar'])
argcomplete.autocomplete(parser)
args = parser.parse_args()
main(**vars(args))
Run Code Online (Sandbox Code Playgroud)
并确保bash知道这个脚本,你使用
eval "$(register-python-argcomplete your_script)"
Run Code Online (Sandbox Code Playgroud)
你应该把这一行放在你的~/.bashrc或遵循argcomplete的文档并激活'全局'完成.
之后,您将按要求完成工作.
这种方式的工作方式是eval行创建一个_python_argcomlete使用注册的函数complete.(运行register-python-argcomplete your_script以查看对bash进行评估的内容).自动完成功能查找由bash完成机制设置的环境变量,以查看是否需要执行操作.如果它起作用,它将退出程序.如果它不起作用,这是对程序的正常调用,该函数什么也不做,程序的正常流程继续.
为了让自动完成工作,你需要一个 bash 函数来生成可能的选项,然后你需要运行complete -F <function_name> <program_name>
最好的方法是让程序根据自己的解析算法生成完成函数,以避免重复。然而,快速浏览一下 argparse,我找不到访问其内部结构的方法,但我建议您寻找它。
下面是一个适用于上述程序的 bash 函数:
function _example_auto() {
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
case "$prev" in
--optional )
COMPREPLY=( $(compgen -W "foo1 foo2 bar" -- $cur) )
return 0
;;
*)
COMPREPLY=( $(compgen -W "--optional spam eggs" -- $cur) )
return 0
;;
esac
}
Run Code Online (Sandbox Code Playgroud)