Bash completion makes bash start slowly

I found a bit hackish solution that seems to work fairly enough.

Solution

At the bottom of ~/.bashrc add:

trap 'source /etc/bash_completion ; trap USR1' USR1
{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

Explanation

trap 'source /etc/bash_completion ; trap USR1' USR1

Setup an handler to be run when the shell receives the signal SIGUSR1; the handler will load the completions and hence it will deactivate itself.

{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

Asynchronously wait a bit then send the signal to the current shell. disown is needed to suppress bash process control feedback. sleep is needed to work asynchronously.

Problems

For some reason the first command issued to this shell will not be recorded in the history.


Update in 2013: Most of bash-completion was rewritten to autoload completions only when needed. The core script is much ligher now.


The completion script can sometimes be huge in shell script standards. On one servers I have access to, it's almost 1700 lines (57 KB) and that's just the core script. In /etc/bash_completion.d there are ~200 additional scripts for various other commands (openssl, mutt, mount...) totalling 25537 lines or 1.2 MB. Each script, when sourced, checks if a command is actually available before defining completion handlers; ~330 times in this case, each of which involves checking $PATH for an executable file with a given name. (Although I would expect /usr/bin to be cached in memory...)

Admittedly, even that only takes half a second to load, not two full seconds. But it might be at least part of the problem. Run du -hs /etc/bash_completion* or wc -l /etc/bash_completion{,.d/*} | grep total if you want to check.


You can try manually sourcing the script, in "trace" mode:

set -x
. /etc/bash_completion

You'll see each line as it is executed. If there's a particular command that takes a long time, you should notice it.

(set +x disables the trace mode.)


You should use the lastest version (2.0) of bash_completion. If you're using Debian, it's in wheezy, but it has no dependencies on any other wheezy package, so you can install it on a squeeze with no issue.

The lastest version loads completion dynamically on the fly, so it divided the prompt load time for me by at least 10x.