gpt4 book ai didi

python - argparse(和已弃用的 optparse)如何在 bash 中响应 python 程序名称后的 'tab' 按键?

转载 作者:太空狗 更新时间:2023-10-29 18:02:34 32 4
gpt4 key购买 nike

我测试了optcomplete使用 optparse 模块。它的例子是一个简单的文件,所以我可以让它工作。我还使用 argparse 模块对其进行了测试,因为不推荐使用之前的模块。但我真的不明白 python 程序是如何以及由谁在 Tab 键上被调用的。我怀疑 bash 连同 shebang 行和 argparse(或 optparse)模块以某种方式参与。我一直在努力解决这个问题(现在要阅读源代码)。

我有一个稍微复杂一点的程序结构,其中包括一个围绕处理参数的代码段的包装器。它的 argparse.ArgumentParser() 实例化和对 add_argument() 的调用——它们被父类(super class)化到另一个中间模块中以避免重复代码,并且正在调用它的包装器——在里面一个功能。

我想了解此制表符补全在 bash 和 python 之间的工作方式(或者就此而言,任何其他解释器,如 perl)。

注意:我对 bash 完成(我刚刚学到的)有相当的了解,而且我认为我了解 bash(仅)自定义完成。

注意:我读过其他类似的 SO 问题,但没有人真正回答这个问题。

编辑:Here是 bash 函数。
我已经了解 python 模块如何通过读取变量的 os.environ 值来了解命令行中键入的单词

$COMP_WORDS
$COMP_CWORD
$COMP_LINE
$COMP_POINT
$COMPREPLY

这些变量只有在按下 Tab 时才有值。我的问题是 python 模块是如何被触发的?

最佳答案

要了解这里发生了什么,让我们检查一下 bash 函数实际做了什么:

COMPREPLY=( $( \
COMP_LINE=$COMP_LINE COMP_POINT=$COMP_POINT \
COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \
OPTPARSE_AUTO_COMPLETE=1 $1 ) )

看到最后的 $1 了吗?这意味着它实际上调用了我们要执行的 Python 文件,并设置了特殊的环境变量!为了跟踪发生了什么,让我们准备一个小脚本来拦截 optcomplete.autocomplete 所做的事情:

#!/usr/bin/env python2
import os, sys
import optparse, optcomplete
from cStringIO import StringIO

if __name__ == '__main__':
parser = optparse.OptionParser()

parser.add_option('-s', '--simple', action='store_true',
help="Simple really simple option without argument.")

parser.add_option('-o', '--output', action='store',
help="Option that requires an argument.")

opt = parser.add_option('-p', '--script', action='store',
help="Option that takes python scripts args only.")
opt.completer = optcomplete.RegexCompleter('.*\.py')

# debug env variables
sys.stderr.write("\ncalled with args: %s\n" % repr(sys.argv))
for k, v in sorted(os.environ.iteritems()):
sys.stderr.write(" %s: %s\n" % (k, v))

# setup capturing the actions of `optcomplete.autocomplete`
def fake_exit(i):
sys.stderr.write("autocomplete tried to exit with status %d\n" % i)
sys.stdout = StringIO()
sys.exit = fake_exit

# Support completion for the command-line of this script.
optcomplete.autocomplete(parser, ['.*\.tar.*'])

sys.stderr.write("autocomplete tried to write to STDOUT:\n")
sys.stderr.write(sys.stdout.getvalue())
sys.stderr.write("\n")

opts, args = parser.parse_args()

当我们尝试自动完成它时,这会为我们提供以下信息:

$ ./test.py [tab]
called with args: ['./test.py']
...
COMP_CWORD: 1
COMP_LINE: ./test.py
COMP_POINT: 10
COMP_WORDS: ./test.py
...
OPTPARSE_AUTO_COMPLETE: 1
...
autocomplete tried to exit with status 1
autocomplete tried to write to STDOUT:
-o -h -s -p --script --simple --help --output

所以 optcomplete.autocomplete 只是读取环境,准备匹配项,将它们写入 STDOUT 并退出。然后将结果 -o -h -s -p --script --simple --help --output 放入 bash 数组 (COMPREPLY=( ... )) 并返回到 bash 以将选择呈现给用户。没有魔法:)

关于python - argparse(和已弃用的 optparse)如何在 bash 中响应 python 程序名称后的 'tab' 按键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9568611/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com