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

Jan*_*Jan 35 bash autocomplete

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

就个人而言,我更喜欢功能较弱的自动完成功能而不是缓慢的自动完成功能。有简单的修复吗?

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

  • PATH 是非常标准的。~/bin 有一些 bash 脚本

    $ echo $PATH
    /home/USERNAME/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    
    Run Code Online (Sandbox Code Playgroud)
  • 工作目录中的文件数小于 100。

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

Gil*_*il' 37

我不知道修复 - 有各种各样的事情可能会导致延迟。但我可以提供一些调查提示。

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

调查的第一步是运行set -x以跟踪 shell 为生成完成而执行的命令。看它停在哪里。

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

  • ps,使用`set +x`返回正常非调试模式 (8认同)
  • 我使用 Unix 的时间很长,但不知道“set -x”,这是一个多么酷的命令。非常“黑客模式参与” (2认同)

Jef*_*ard 22

如果您的 *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
Run Code Online (Sandbox Code Playgroud)

确认:我确认了这一点,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
Run Code Online (Sandbox Code Playgroud)

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

  • 同样的问题(Debian 8.5)早在 2 1/3 年前,解决方案就像一个魅力。Debian 8.6 没有这个问题。 (2认同)
  • 我已经使用 set -xa 一百万次了,但我没想到它会*也*显示完成性能问题,非常感谢! (2认同)

小智 6

我建议检查您的系统音频是否正常工作。终端铃声无法正常播放可能是暂时冻结的原因。例如:PulseAudio Daemon 崩溃/工作不正常。

在我的终端中,当我第一次按下 Tab 键时,它卡住了几秒钟。之后就好了。如果终端中的所有文本都被擦除并按下退格键,也会发生这种情况。

我尝试了上述所有方法,但都没有奏效。

关闭终端铃声

Ctrl+ Alt+ T--> 编辑 --> 首选项 --> {用户配置文件,通常未命名} --> 文本 --> 声音 --> 取消选中终端铃声