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.

link|improve this question
is this /bin/bash ? - try /bin/dash might be a bit quicker. – Sirex Apr 7 '11 at 12:40
This is why I deinstalled bash-completion – Vi. Apr 7 '11 at 13:47
feedback

2 Answers

up vote 2 down vote accepted

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

link|improve this answer
Feature creep even in simplistic text mode? It's more likely than you think. – Vi. Apr 7 '11 at 13:48
@Vi: After seeing zsh compile its startup scripts to bytecode... – grawity Apr 7 '11 at 13:52
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 '11 at 15:42
feedback

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'

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.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.