Mik*_*nov 0 bash argparse python-3.x
当我在 python3 中使用 arparse 时,我发现了一些奇怪的事情。
#!/usr/bin/env python3
import argparse
def create_parser():
p = argparse.ArgumentParser(add_help=True)
p.add_argument('-i', help='i parameter', required=True)
p.add_argument('-m', help='m parameter', required=True)
return p
if __name__ == '__main__':
p = create_parser()
n = p.parse_args()
print(n)
Run Code Online (Sandbox Code Playgroud)
当我尝试启动它时
python3 ./script.py -i ./some_folder/some_file -m ./
Run Code Online (Sandbox Code Playgroud)
bash 自动完成与“-i”参数一起工作,但不能与“-m”一起工作。例如,如果我将“-m”重命名为“-me”,则一切正常。
在 bash 中,我尝试使用“-m”参数启动其他命令,但它不仅适用于 argparse。这里哪里会出错?
这里发生的事情是命令的自动完成python3开始:
$ complete | grep python
complete -F _python python2
complete -F _python python3
complete -F _python python
Run Code Online (Sandbox Code Playgroud)
_python处理它的函数应该是这样的:
$ type _python
_python is a function
_python ()
{
local cur prev words cword;
_init_completion || return;
case $prev in
-'?' | -h | --help | -V | --version | -c)
return 0
;;
-m)
_python_modules "$1";
return 0
;;
-Q)
COMPREPLY=($( compgen -W "old new warn warnall" -- "$cur" ));
return 0
;;
-W)
COMPREPLY=($( compgen -W "ignore default all module once error" -- "$cur" ));
return 0
;;
!(?(*/)python*([0-9.])|-?))
[[ $cword -lt 2 || ${words[cword-2]} != -@(Q|W) ]] && _filedir
;;
esac;
local i;
for ((i=0; i < ${#words[@]}-1; i++ ))
do
if [[ ${words[i]} == -c ]]; then
_filedir;
fi;
done;
if [[ "$cur" != -* ]]; then
_filedir 'py?([co])';
else
COMPREPLY=($( compgen -W '$( _parse_help "$1" -h )' -- "$cur" ));
fi;
return 0
}
Run Code Online (Sandbox Code Playgroud)
完成函数将-m标志作为参数显示为 python 或脚本的相同处理,因此它尝试使用模块名称列表来完成。
解决此问题的一种方法是为python3不会触发完成的命令使用别名,例如:
$ alias py3=python3
Run Code Online (Sandbox Code Playgroud)
为了使这个持久化,你可以把它放在你的~/.bashrc. 然后你可以使用
$ py3 ./script.py -i ./some_folder/some_file -m ./[TAB]
Run Code Online (Sandbox Code Playgroud)
这将使用文件名完成。
或者将-m标志重命名为其他名称。