Ale*_*der 13 bash bash-completion
我有一个命令行工具,它以三部分形式接受参数:
$ t first_second_third
Run Code Online (Sandbox Code Playgroud)
我有一组有效值first,一组有效值second,以及一组有效值third.我想使用Bash完整功能来完成选项值的每个部分,如下例所示:
$ t [tab][tab] # shows options for first part
walk run skip bike
$ t w[tab] # completes first part and appends delimiter
$ t walk_[tab][tab] # shows options for second part
home work park
$ t walk_h[tab] # completes second part and appends delimiter
$ t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$ t walk_home_a[tab] # completes second part and appends space
$ t walk_home_afternoon
Run Code Online (Sandbox Code Playgroud)
我有这个代码:
_tool () {
local cur="${COMP_WORDS[COMP_CWORD]}"
local first="walk run skip bike"
local second="home work park"
local third="morning afternoon evening"
case "${cur}" in
*_*_*)
COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;;
*_*)
COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
*)
COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
esac
}
complete -F _tool t
Run Code Online (Sandbox Code Playgroud)
第一个条款很有效; 没什么特别的.但第二个条款没有给我任何选择或完成.
$ t [tab][tab]
bike_ run_ skip_ walk_
$ t b[tab]
$ t bike_[tab][tab] # nothing but bells
Run Code Online (Sandbox Code Playgroud)
我用以下代码替换了第二个子句(即我${cur}在COMPREPLY调用中用空字符串替换):
COMPREPLY=( $(compgen -W "${second}" -S "_" -- "") ); compopt -o nospace; return 0;;
Run Code Online (Sandbox Code Playgroud)
我在命令行上获得了所有选项的列表,但没有完成.
$ t bike_[tab][tab]
home_ park_ work_
$ t bike_h[tab][tab]
home_ park_ work_
$ t bike_ho[tab][tab]
home_ park_ work_
Run Code Online (Sandbox Code Playgroud)
我想可能有一些不良的相互作用${cur}和COMPREPLY单词列表,所以我又换了第二条,加上其当前单词的第一部分相匹配的前缀:
local prefix=( $(expr "${cur}" : '\(.*_\)') )
COMPREPLY=( $(compgen -W "${second}" -P "${prefix}" -S "_" -- "") ); compopt -o nospace; return 0;;
Run Code Online (Sandbox Code Playgroud)
这没什么用.随着${cur}在静止COMPREPLY的命令,我没有选择或完成一次.换了一个空字符串,我得到了完整的选项(不仅仅是当前的部分).但是,按Tab键会删除键入的内容.
$ t bike_[tab][tab]
bike_home_ bike_park_ bike_work_
$ t bike_ho[tab]
$ t bike_ # "ho" was erased
Run Code Online (Sandbox Code Playgroud)
当然,我对第三部分也有同样的问题.
这类似于另一个Bash完整问题,但我不想列出值的每个可能的排列,并且它们没有被格式化为文件名(不确定文件名模式是否有所不同).
谢谢您的帮助!
留学美国相关考试
我能够创造你想要的。请参阅下面的代码:
_tool () {
local cur="${COMP_WORDS[COMP_CWORD]}"
local first="walk run skip bike"
case "${cur}" in
*_*_*)
local firstsecond=`echo ${cur} | awk -F '_' '{print $1"_"$2}'`
local third="${firstsecond}_morning ${firstsecond}_afternoon ${firstsecond}_evening"
COMPREPLY=( $(compgen -W "${third}" -- ${cur}) ); return 0;;
*_*)
local firstcomp=`echo ${cur} | awk -F '_' '{print $1}'`
local second="${firstcomp}_home ${firstcomp}_work ${firstcomp}_park"
COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
*)
COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
esac
}
complete -F _tool t
Run Code Online (Sandbox Code Playgroud)
我对自动完成不太熟悉,这是我第一次使用compgen或complete,所以我不确定我能回答你关于事物理论的问题。我可以告诉你我做了什么,以防它帮助你理解这个记录错误的函数是如何工作的。首先,我试图了解你所拥有的。我成功地重现了您的问题。然后我有了这样的想法,即使你不想在代码中自己列出每个排列,我也可以使用局部变量来模拟,好像它有一样。我做的第一件事是在我们有了第一个下划线后获取“第一个”元素,然后向其中添加第二个元素,并将其提供给 compgen。令我惊讶的是,它运行良好。然后我尝试对第三级做同样的事情......然后问题开始了。我发现第二部分并没有我想象的那么好。完成第一个词后,我会得到第二个词的建议;
$ t [tab][tab] # shows options for first part
bike_ run_ skip_ walk_
$ t w[tab] # completes first part and appends delimiter
$ t walk_[tab][tab] # shows options for second part
walk_home_ walk_park_ walk_work_
$ t walk_h[tab] # completes second part and appends delimiter
$ t walk_home_[tab][tab] # screws up with it
$ t walkhome_
Run Code Online (Sandbox Code Playgroud)
我尝试将下划线移动到 awk 中,但没有成功:
local first=`echo ${cur} | awk -F '_' '{print $1"_"}'`
local second="${first}home ${first}work ${first}park"
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我不得不将变量名更改为与“first”不同的名称,然后它就开始工作了。然后,在第三个元素上,我遇到了您最后描述的相同问题,我在第三个元素中输入的任何内容都会消失,但是 [tab][tab] 会给我以下选项:
$ t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$ t walk_home_aft[tab] # erases what I typed
$ t walk_home_
Run Code Online (Sandbox Code Playgroud)
我${cur}在第三个单词中添加到 compgen 并且它起作用了。这只是我所做工作的总结......但我得到了一个工作版本,所以我很高兴。:-)