shell 补齐路径_bash shell:命令的文件名自动补全设置

大家都知道 bash

里有个文件自动补全功能,按两下 Tab 键显示出候选补全文件名,不同程序会显示相应的文件类型(根据扩展名来判断),例如

mplayer 会显示媒体文件(如 avi、mpg、mkv),而不会显示文本文件(如 txt、cfg、ini),而 Vim

则是反过来,这样的一直以来相当好用,不过还是有些时候还是挺烦人的。

有时我想用 Vim 的 diff 功能来比较文件,比如两个 java 的

class 文件,虽然 class 文件是二进制文件,但在 Vim 中可以转换成十六进制来显示,方便比较。打了 Vim

命令后,按两下 Tab 并补全候选不会有

class 文件,所以你得手动输入。

mplayer

的一个参数 -ass-styles,这个参数用于使用外部

ass 字幕的样式,后面接一个 ass 文件的路径,用样也不会显示出来,因为 bash 的自动补全里并没有为这个参数定义过。

这两个例子只是最近用到,其实一直以来也遇过这种情况,很多时候我会把按两次 Tab 来当

ls

命令使用,看看目录下有什么文件,但这样会让某些文件没显示出来,让你误以为文件不存在,当前目录短文件名就直接输入算了,好几层的目录和长文件名就麻烦,对于这种情况,我的土方法是

把打了一半的命令行 Ctrl

+ c 掉,然后用 ls 看列一下,复制粘贴路径出来

或者先直接补全路径后,把光标移回开头输入命令名

这样太不够效率了,尤其是在调试时,命令参数记得比路径还要熟的,干脆关掉这个文件扩展名检测功能好了。

我记得 bash 的补全脚本在

/etc/bash_completion,这个文件好长,稍微看了一下,发现有关联的代码,比如这段看来就是定义补全的扩展名

complete -f -X '!*.fig' xfig

complete -f -X '!*.@(mid?(i)|MID?(I)|cmf|CMF)' playmidi

complete -f -X '!*.@(mid?(i)|MID?(I)|rmi|RMI|rcp|RCP|[gr]36|[GR]36|g18|G18|mod|MOD|xm|XM|it|IT|x3m|X3M|kar|KAR)' timidity

complete -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' vi vim gvim rvim view rview rgvim rgview gview

complete -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' emacs

complete -f -X '!*.@(exe|EXE|com|COM|scr|SCR|exe.so)' wine

直接执行 complete 会输出当前定义过补全的命令,看样子也是在

/etc/bash_completion 里定义的

$ complete | grep " mplayer\| vim"

complete -o filenames -F _mplayer mplayer

complete -o filenames -F _filedir_xspec vim

man 了一下 complete 命令,没有手册,属于 builtin

命令,上网找,简介在 这里 ,用法在

大概看了一下用法,就是 complete

补全行为选项 命令名

-F:执行指定函数名,候选结果保存在 COMPREPLY 数组变量里,补全功能更强大,可以实现命令参数补全,函数名在

/etc/bash_completion 定义的。

-f:补全文件名,后可跟 -X 参数。

-X:过滤表达式,符合表达式的文件名会被排除,即不会在补全候选显示出来,如果以感叹号开头,则表示反转,即符合表达式的文件名才显示。

-o:补全类型,filenames 表示补全的是一个文件,跟 -f 参数使用才有效;其它值如 dirnames 表示补全目录。

-F 执行的函数比 -f

-X 更早执行,这样说起来有点混乱,我测试了一下,

当你输入好「命令名 」,按两下Tab键,开始补全。

bash

执行了 -F 指定的函数,函数执行完后输出数组变量 COMPREPLY 的结果,这个变量值有可能为空。

继续根据 -f

-X 里的表达式,符合表达式的文件名不则显示,同时结果再根据 -o 指定补全类型来决定是否显示。

就以 Vim 和 mplayer 举例

对于 Vim 来说,它最终被定义的行为这样

complete -o filenames -F _filedir_xspec -f -X '*.@(o|so|so.!(conf)|a|rpm|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MPG|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)' vim

先执行 _filedir_xspec 函数,而这个函数执行后变量 COMPREPLY 为空,所以什么也没输出。接着补全文件名,可以看 class 字符串在表达式里面,所以不显示。如果删掉 class| 再运行,就可以匹配

class 文件了。

对于mplayer,它最终被定义的行为这样

complete -o filenames -F _mplayer mplayer

先执行了 _mplayer 函数,这个函数在

/etc/bash_completion 代码非常多,mplayer 的选项参数都打上去了,所以能补全 mplayer

的选项参数。到补全文件名时,没有指定过滤表达式,所以什么都没做。亦即它的补全功能全由 _mplayer 函数完成。

以上结果纯属连猜带蒙,若有错误,烦请指正,为了介绍一个小功能码了这么多字容易嘛我,所以

临时禁用 Vim 的补全功能就是

complete vim

保留路径补全,但不要扩展名检测,不指定「-X」即可

complete -f vim

只补全文件

complete -o filenames -f vim

只补全目录

complete -o dirnames vim

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值