为自定义脚本添加自动完成功能

Modified on: Sat, 30 Jun 2018 06:31:30 +0800

我目前正在开发一个名为makeyourself.sh(链接到/usr/bin/mys)的shell脚本,它自动从源代码安装debian软件包(通过apt-get source -b $1)。

所以我决定为包名添加一个自动完成函数作为第一个参数:sudo mys panth<tab><tab>然后应列出以panth - 我的尝试如下:

complete -C "apt-cache --no-generate pkgnames" mys

但它似乎不起作用:当我按上面提到的tab键时,将参数更改为mys,它返回sudo mys mys

我做错了什么?我是否必须在命令中指定complete必须插入要完成的字符串的位置,如{}$1?< / p>

我使用基于Ubuntu的Linux发行版ElementaryOS。该脚本是标准的* .sh shell脚本,它使用标准的#!/bin/bash

作者:,Luke

最佳答案

您怀疑,该命令会收到有关要完成的内容的一些信息。这在手册中有记录,但不在文档complete内置,您需要阅读关于可编程完成的介绍部分

  

调用使用-F-C选项指定的任何shell函数或命令。调用命令或函数时,COMP_LINECOMP_POINTCOMP_KEYCOMP_TYPE变量被赋值为如上所述(请参阅Bash Variables)。如果正在调用shell函数,则还会设置COMP_WORDSCOMP_CWORD变量。当调用函数或命令时,第一个参数是其参数正在完成的命令的名称,第二个参数是正在完成的单词,第三个参数是在当前命令行上完成的单词之前的单词。不执行针对正在完成的单词的生成的完成的过滤;函数或命令可以完全自由地生成匹配项。

因此使用三个参数调用该命令:

  • 命令名称 - 因此您可以在一个脚本中组合类似命令的完成。
  • 要完成的单词 - 因此您可以将输出限制为将要过滤的前缀。
  • 上一个词 - 有用的例如完成选项。

相同的参数传递给完成函数(complete -F somefunction)。请注意,无论您使用的是函数还是命令,都可以过滤所需的匹配项。

根据您的尝试,最终执行的命令是apt-cache --no-generate pkgnames mys '' mys。这将打印以mys开头的软件包名称列表(apt-cache pkgnames仅查看第一个操作数)。最长的公共前缀是mys,所以bash开始完成mys并希望你选择下一个字母。

鉴于参数附加到命令(未作为位置参数传递 - -C的参数被解析为shell命令),没有简单的方法来解析它们。最简单的解决方案是使用包装函数。

_mys () {
  COMPREPLY=$(apt-cache --no-generate pkgnames "$2")
}
complete -F _mys mys
作者:,Gilles

相关问答

添加新评论