为什么 bash 完成在 OS X 上加载如此缓慢?

dis*_*dng 20 bash macos

我不明白为什么 bash 完成在我的 MacBook Pro 上加载如此缓慢。

我在我的~/.bash_profile

echo "Loading BashCompletion..."
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi
echo "BashCompletion loaded."
Run Code Online (Sandbox Code Playgroud)

bash_completion 的执行时间通常 > 2 秒。

当我在需要我不断打开新标签的终端上工作时,我发现这真的很烦人。

有没有办法可以缓存这个或其他东西?

(请注意,我使用的是 iTerm2,这在 Mac 的原始终端上也同样慢)。

dan*_*lan 13

对于任何人来的结论是,启动时间为新壳在MacOS是对他们来说太缓慢,这是解决方案

我刚刚发现实际上有两个包可以通过brew. 我已经安装这个bash-completion包多年了,从来没有费心去质疑它,即使在那段时间我已经从 Bash 3,到 4,再到现在的 5。不过,我会时不时地重新审视这个问题,经常偶然发现这个 StackOverflow 讨论。

还有一个包,bash-completion@2

有什么不同?bash-completion适用于 Bash 3.2 版。bash-completion@2适用于 Bash 版本 4.1+ 和 5。

在删除旧bash-completion包并安装 时bash-completion@2,我的 shell 启动时间从 605 毫秒下降到 244 毫秒。这是一个巨大的速度提升。

我怀疑我们中的许多人都犯了同样的错误,因为brew info统计数据显示前者的安装量很大,而后者的安装量很少:

在此处输入图片说明

应该注意的是,当前选择的答案提到注释掉一些行,这仅对启动时间有轻微的改善(如果使用旧bash-completion包,很多可能是),但对新bash-completion@2包没有任何影响:这个新包无论如何都很快。这意味着不需要黑客。

特尔;博士:

brew uninstall bash-completion && brew install bash-completion@2
Run Code Online (Sandbox Code Playgroud)

请记住在您的.bashrc.bash_profile文件中更新完成文件的源路径。

资料来源:


作为一个有点相关的主题,我经常使用该rclone实用程序,因此已安装它。它也恰好拥有我见过的最大的完成文件。删除它可以将我的 shell 启动时间缩短到大约 120 毫秒,这非常快。


编辑:

对于任何想要解释这个问题的技术细节的人,我已经在 Homebrew 论坛上详细介绍了它。总而言之,bash-completion@2速度如此之快的原因是因为它被编写成不再急切地加载所有完成文件;相反,它按需加载完成文件,或者如作者所描述的那样,它以非急切的方式加载它们。


god*_*byk 10

简短版本:删除单行/usr/local/etc/bash_completion将打开新标签的时间从十秒减少到四分之一秒。请继续阅读以了解详细信息。

我正在使用自制软件的 bash-completion 并遇到了同样的问题。每次打开终端时,加载 bash 完成脚本需要十多秒钟。

大多数时候,它似乎被have()函数中的一行占用:调用type以确定是否安装了命令行程序。

使用默认have()函数和所有提供的 bash 完成脚本,加载脚本需要 10.561 秒(通过在我的文件中添加前缀time来报告。. /opt/local/etc/bash_completion.bash_profile

在注释掉PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&我的/usr/local/etc/bash_completion脚本行后(离开该have=yes行,打开一个新终端只需要 0.258 秒。这个时间可以通过从/usr/local/etc/bash_completion.d目录中删除不必要的完成脚本(符号链接)来进一步减少。

我不知道为什么打电话type要花这么长时间。我接下来研究一下。

这种方法的一个潜在缺点是它会导致 bash 完成函数被加载到内存中,即使您没有使用它们。该have()函数检查是否安装了命令或应用程序。如果不是,完成脚本通常决定不去加载自己,因为它没有用。

目前,我对这种权衡感到满意,但我会在type有时间的时候继续探索这个问题。如果我找到更好的解决方案,我会更新我的答案。


小智 -1

如果您运行的是 MacPorts >= 2.1.2 和 Mountain Lion,那么您的想法似乎bash_profile是错误的。按照如何让 git-completion.bash 在 Mac OS X 上工作? 的说明进行操作。。我认为这可以加快自动完成的速度。

\n\n

另一种解决方案是尝试通过Fink或 Homebrew 安装自动完成功能。如果这不起作用,您可以尝试另一个 shell。我发现Fish shell在自动完成(开箱即用)方面非常出色。虽然版本 2 仍处于测试阶段,但我强烈推荐它。

\n