Starting a bash on my ubuntu system takes about 2 seconds. If I remove loading /etc/bash_completition in .bashrc it starts without delay. Of course I don't want to give up completition and I don't think loading that file is legit reason for a 2 seconds delay.

Any ideas how i can find out what the problem is or how i can speed things up.

  • is this /bin/bash ? - try /bin/dash might be a bit quicker.
    – Sirex
    Apr 7, 2011 at 12:40
  • 3
    This is why I deinstalled bash-completion
    – Vi.
    Apr 7, 2011 at 13:47

4 Answers 4


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.)

  • Feature creep even in simplistic text mode? It's more likely than you think.
    – Vi.
    Apr 7, 2011 at 13:48
  • @Vi: After seeing zsh compile its startup scripts to bytecode... Apr 7, 2011 at 13:52
  • 1
    Thank you. Thats was really easy. Sadly all commands were not noticable different. So it looks like its indeed the massive amount whats causing the problem.
    – user75250
    Apr 7, 2011 at 15:42

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


At the bottom of ~/.bashrc add:

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


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.


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

  • 1
    This doesn't seem to give a startup boost - time bash -lc true reports ~0.12s with or without this, even though time source /etc/bash_completion reports higher numbers like 0.26s. Has this effectively been fixed?
    – l0b0
    Apr 11, 2013 at 14:25
  • I don't know if time bash -lc true works properly here since true finishes before ~0.1s so it doesn't source anything. Anyway time source /etc/bash_completion reports ~0.17s here and that's about the time I need to wait for the PS1 appear.
    – cYrus
    Apr 13, 2013 at 12:21
  • 2
    Ingenious! In explanation, the trap commands misses a USR1 at the end. Feb 20, 2014 at 6:02
  • With SIGUSR, the signal handler is not invoked until after I press enter at the shell prompt. There is a pause at that point while it runs. I switched to SIGQUIT and it seems to work fine.
    – Jon Nalley
    Feb 1, 2018 at 4:03

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.


You can use a placeholder while the completions are loading; it should be enough to trick your eyes. This obviously work only if the time needed by source /etc/bash_completion is less than the time needed by you to type and issue the first shell command, otherwise it will be delayed as well.

The idea is to echo a fake PS1, source the completions and finally erease the terminal.

Suppose that your PS1 is \u@\h:\w\$, they you might write something like:

echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'


  • 2J erases the terminal;
  • H move the cursor to the upper right corner.

Note: You may want to check if the user is root and use # instead of $ for consistency:

echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "

Note: Removing \e[2J avoids the flickering but it will leave junk characters if the placeholder is longer than the actual prompt.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .