Skip to main content

Getting rid of bash annoyances

$ zcat /boot/initrd.<tab><tab><TAB!>

I know the file is there and I know it’s a file an application can handle, but bash autocompletion tries to be smart by refusing to provide the file name.

This gets really annoying if you happen to work with files that don’t have an extension the autocompletion scripts expect or you are running a command using sudo and want to pass the filename.

There is a dedicated shortcut for filename completion – M-/ by default, but I’ve never used tab completion for options and that means that I can get rid of it.

There is no need to uninstall anything, adding complete -r to .bashrc will remove all the completion functions.

To completely disable programmatic completion, add shopt -u progcomp to .bashrc.

$ zcat /boot/initrd.img-3.<tab>
initrd.img-3.2.0-29-generic         initrd.img-3.7.0-7-generic
initrd.img-3.2.0-35-generic         initrd.img-3.8.0-030800rc2-generic

Nice.

Another thing that was annoying me for a while is command-not-found package. It is extremely helpful at discovering what package the application I want is in. However, there were quite a few times when I made a typo, pressed Enter, noticed it right away but had to wait for a second or so before I got the “command not found” and the prompt back. When disk is really busy, making a typo costs me another 30 seconds of disk trashing before command-not-found comes up with a friendly suggestion that killal is better spelled as Command 'killall' from package 'psmisc'.

Having command-not-found installed and available but not kicking in on every occasion is preferred. The function bash runs in case it can’t find the command is command_not_found_handle so we simply need to unset this function in .bashrc and add an alias (in my case packages-providing after LP:486716, but it can be anything) which will execute the real command-not-found script:

unset command_not_found_handle
alias packages-providing='/usr/lib/command-not-found --no-failure-msg'

So now I will be given the package name only when I want it:

$ sl
bash: sl: command not found

$ packages-providing sl
The program 'sl' is currently not installed. You can install it by typing:
sudo apt-get install sl