如何在bash中调试和修复缓慢的自动完成功能?


26

在最近更新(Ubuntu 12.04 LTS)之后,命令行上的TAB完成速度很慢。输入部分命令(例如evi [TAB])或部分文件名(例如evince somedocu[TAB])后,外壳有时(尽管并非总是)挂起几秒钟。

就个人而言,我宁愿使用功能较弱的自动完成程序也不愿使用较慢的自动完成功能。有简单的解决方法吗?

编辑:与评论有关的其他信息:

  • PATH非常标准。〜/ bin有一些bash脚本

    $ echo $PATH
    /home/USERNAME/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    
  • 工作目录中的文件数少于100。

  • 在异常磁盘活动(系统升级)之后,自动完成功能特别慢。因此,有可能重新读取/ usr / bin和其他目录会导致延迟。

4
是不是通过更新启用了硬盘速度管理,并且自动完成功能等待磁盘唤醒以计算自动完成功能?
Vincent Nivoliers

2
是否取决于当前目录中有多少个文件?
terdon

1
#echo $ PATH说什么?如果路径中的目录中有许多文件(成千上万个或更多),则可能是造成此问题的原因。
斯蒂芬

Answers:


28

我不知道如何解决-各种各样的事情都可能导致延迟。但我可以提供一些提示进行调查。

就像一个猜测一样,也许搜索路径中的某个目录($PATH或bash在其中查找完成数据的某个地方)的文件系统响应速度很慢。通常是远程文件系统运行缓慢,但是也可能是硬盘故障,FUSE驱动程序挂起等。

研究的第一步是运行set -x以获取Shell执行以生成补全的命令的跟踪。看着它停在哪里。

如果那不能提供足够的信息,请带上大手笔。注意外壳程序的进程ID(echo $$)。在另一个终端中,运行strace -f -s9999 -p$$(如果在另一个unix风格上运行,则等效于strace)。Strace列出了该进程执行的系统调用。查看是否似乎正在访问不应访问的文件,或者访问某些文件的速度是否很慢。将选项添加-Tstrace命令行可以显示每个系统调用所花费的时间。


1
我一直在使用Unix并且不知道的时间set -x,这真是个很酷的命令。非常“参与黑客模式”
马特·弗莱彻

6
ps,用于set +x返回正常的非调试模式
Matt Fletcher

19

如果您将* nix框设置为LDAP客户端,则可能会出现此问题,甚至以本地用户身份登录也是如此。

无聊的调试信息:使用调试set-x,我发现挂起的完成项位于:

> set -x
> ls foo<tab>
...                     <--- lots of output removed
...
+ _quote_readline_by_ref foo quoted
+ '[' -z foo ']'
+ [[ foo == \'* ]]      <--- froze here
+ [[ foo == ~* ]]       <--- actually causing the trouble

确认:我确认了这一点,ls ~*它也挂了。原来我的ldap服务器很慢,但这不应该影响bash的完成和ls!

解决方案:啊哈,有一个针对bash-completion + ldap 的bug,它将在较新的版本中修复,并且如果您不想等待,可以修复一个简单的补丁。标签页的完成又很快了,万岁!

这是补丁文件,以防链接消失。它只是在第545和547行上转义〜

--- /usr/share/bash-completion/bash_completion.orig 2014-11-06 10:36:14.981888369 +0100
+++ /usr/share/bash-completion/bash_completion  2014-11-06 10:36:25.142070963 +0100
@@ -542,9 +542,9 @@
     elif [[ $1 == \'* ]]; then
         # Leave out first character
         printf -v $2 %s "${1:1}"
-    elif [[ $1 == ~* ]]; then
+    elif [[ $1 == \~* ]]; then
         # avoid escaping first ~
-        printf -v $2 ~%q "${1:1}"
+        printf -v $2 \~%q "${1:1}"
     else
         printf -v $2 %q "$1"
     fi

您需要退出当前的ssh会话并重新登录,此补丁才能生效。


1
我遇到了这个确切的问题,补丁很不错
radman '16

2
同样的问题在这里(Debian 8.5)2 1/3年之前,解决方案就像一个咒语。Debian 8.6没有问题。
YoMismo

2
我已经使用了-xa百万次,但我从未想到它还会显示完成性能问题,非常感谢!
MarcH

Debian 9.8遇到了这个问题!
菲利普·加乔德

0

尝试重新安装bash-completion

sudo apt-get install --reinstall bash-completion

对我来说,这已在Ubuntu 18.04.3 LTS中修复


0

也有人使用额外的自动完成功能,例如Git bash自动完成。Bash完成速度缓慢可能是由于这些额外的自动完成功能行为不当所致。

在我的情况下,这是Git bash自动完成,我的git公钥已更新,因此它进行的身份验证尝试失败导致挂起。一旦我删除了自动完成程序,它又很快了。因此,我的解决方案是修复密钥并重新启用它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.