7 bash tcsh tab-completion bash-completion
我试图在tcsh和/或bash中设置目录完成(两者都在我的网站上使用)稍微扭曲:对于特定命令"foo",我想完成使用自定义函数来匹配first/-deimited term到实际子树节点,然后按照正常目录完成任何连续的术语.它是cdpath和completion的组合,或者我想一种目录完成形式,其中起点由完成脚本控制.它的工作原理如下:
$ foo xxx<TAB>
(custom completion function produces choices it finds at arbitrary levels in the dir tree)
xxxYYY xxxZZZ xxxBLAH ...
foo xxxYYY/<TAB>
(normal directory completion proceeds from this point on, to produce something like:)
foo scene/shot/element/workspace/user/...
Run Code Online (Sandbox Code Playgroud)
我们想这样做是因为我们有一个大型的生产开发树(这是一个CGI生产设施),精通外壳的用户一直在导航和跳跃.抱怨是树的上层是繁琐和多余的; 他们只需要在第一个学期快速搜索,找到可能的"头部"选择并从那里完成目录.似乎可编程完成可以提供一种方法来实现这一点,但它变得相当难以捉摸.
我做了几次自定义bash和tcsh完成的尝试,但是我得到的最接近的是一种"单词完成"形式,用户必须将目录级别视为带空格的单独单词(例如foo scene/shot)/element/workspace/...).我可以继续攻击我目前的脚本 - 但我一直想知道是否有一些我不理解的东西 - 这是我第一次尝试完成程序,而且这些文档和示例在shell书籍和互联网上相当薄弱.如果有任何完成大师可以让我走上正轨,我会很感激.
FWIW:这是我到目前为止所得到的(首先是tcsh,然后是bash).请注意,静态根"/ root/sub1/sub2/sub3"只是搜索功能的占位符,可以在不同级别找到不同的匹配项.如果我可以让它工作,我可以稍后进入搜索功能.同样,两个示例都执行单词完成,这需要用户在每个匹配的术语后键入一个空格(我还必须删除函数中的空格以构造实际路径,哎呀!)
TCSH示例(注意该函数实际上是一个bash脚本):
complete complete_p2 'C@*@`./complete.p2.list.bash $:1 $:2 $:3 $:4 $:5 $:6 $:7 $:8 $:9`@@'
#!/bin/bash --norc
# complete.p2.list.bash - Completion prototype "p2" for shotc command
# Remove spaces from input arguments
ppath=`echo $@ | sed -e 's/ //g'`
# Print basenames (with trailing slashes) of matching dirs for completion
ls -1 -d /root/sub1/sub2/sub3/$ppath* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}'
Run Code Online (Sandbox Code Playgroud)
基础示例:
_foo()
{
local cur prev opts flist
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# Get all command words so far (omit command [0] element itself), remove spaces
terms=`echo ${COMP_WORDS[@]:1} | sed -e 's/ //g'`
# Get basenames (with trailing slashes) of matching dirs for completion
flist=`ls -1 -d /root/sub1/sub2/sub3/${terms}* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}' | xargs echo`
COMPREPLY=( $(compgen -W "${flist}" ${cur}) )
return 0
}
complete -F _foo foo
Run Code Online (Sandbox Code Playgroud)