当我输入evince
,然后按 Tab 时,bash shell 将列出可以通过 打开的所有文件evince
,这似乎是基于文件名的 ext 部分。
这是由 shell 还是应用程序完成的evince
?
如果是前者,shell 如何知道应用程序需要什么?
答案1
在 shell 中运行
这里有两个单独的问题:
哪里完成实施的,以及
其他哪些软件组件它属于吗。
完成的实现与命令行编辑器密切交互,命令行编辑器是 shell 的一部分;基本上它需要在外壳中运行。
很大一部分的完成是实现为外壳函数在大多数 shell 中;
单独包装
您询问它是否是应用程序的一部分,或者外壳的一部分;
实际上,它既不是第一,也不是第二,而是独立的。
Ubuntu 下的大多数完成都在单独包装 bash-completion
,您可能期望的大量完成作品。
不是 bash 的一部分,而是独立管理和发布。
代码
让我们看一下您的完成示例evince
:
$ apt-file list bash-completion | grep evince
bash-completion: /usr/share/bash-completion/completions/evince
$ ls -l /usr/share/bash-completion/completions/evince
-rw-r--r-- 1 root root 967 Apr 7 16:10 /usr/share/bash-completion/completions/evince
有趣的!我们不需要寻找 PDF 查看器的补全等通用内容,而是找到了与evince
.
该文件包含shell函数的实现;它的一部分由描述如何在命令行上使用的字符串常量组成evince
- 最有趣的部分/usr/share/bash-completion/completions/evince
是:
_evince() {
[ ... ]
case $prev in --gdk-no-debug|--gtk-module|--gtk-debug|--gtk-no-debug|\
-p|--page-label|-i|--page-index|-l|--find|--display)
[ ... ]
_filedir '@(@(?(e)ps|?(E)PS|[pf]df|[PF]DF[...]|bmp|xpm|ico|xwd|tga|pcx)'
[ ... ]
它描述了常规选项(如 )--gtk-debug
、应用程序特定选项(如 ),--page-label
并列出了可以由 和 处理的文件扩展evince
名.eps
。.pdf
动手实践
您可以使用内置函数显示当前 shell 中定义的函数declare
。如果您在新 shell 中尝试这样做,您会收到一条错误消息:
$ declare -f -p _evince
bash: declare: _evince: not found
假设该包bash-completion
已安装,这仅意味着该功能尚未加载。
因为有一个大数字诸如此类的函数,并且在一个交互式 shell 会话中只使用了其中的几个,因此仅在真正需要函数时才加载函数,而不是在启动时加载所有函数是有意义的。
为了加载该函数,我们尝试通过使用完成来使用它evince
。将光标置于 处|
,按Tab键;
$ evince -|<TAB>
可能会显示一些完成情况。现在,该函数应该被加载,如果我们打印它,它看起来就像上面的文件一样:
$ declare -f -p _evince
要列出所有函数名称,或查看当前加载的所有函数(包括与完成无关的函数),请使用:
$ declare -F | less
$ declare -f | less