Bash – How to Hide Commands from Bash Completion

autocompletebash

In bash, suppose I have these commands:

$ pyt[TAB][TAB]
pytest
python
python-config
python-dbg

99% of the time, I'd go for python. It's so annoying that pytest pops up and prevents me from typing only pyt[TAB][RETURN] to invoke python. Can I hide pytest from bash completion?

My limitations:

  1. I know that I can remove the pytest binary at /usr/bin/pytest to prevent that suggestion within bash. But what if I have no root access? What if pytest is an important script that must exist in order to let other scripts work properly?

  2. Even though I can remove the pytest binary (and I've done it before), some time when I upgrade my software, this script comes back again.

  3. I know that I can use an alias to save keystrokes for my favorite applications (maybe just p for python). But I don't like these non-standard abbreviations. It kind of makes me confused when I remote to other machines.

So, is there any way to hide some commands from bash completion? Answers in other shells (zsh, fish, etc) are welcome since bash doesn't speed up my workflow lately.

Best Answer

This is rather new, but in Bash 4.4 you can set the EXECIGNORE variable:

aa. New variable: EXECIGNORE; a colon-separate list of patterns that will cause matching filenames to be ignored when searching for commands.

From the official documentation:

EXECIGNORE

A colon-separated list of shell patterns (see Pattern Matching) defining the list of filenames to be ignored by command search using PATH. Files whose full pathnames match one of these patterns are not considered executable files for the purposes of completion and command execution via PATH lookup. This does not affect the behavior of the [, test, and [[ commands. Full pathnames in the command hash table are not subject to EXECIGNORE. Use this variable to ignore shared library files that have the executable bit set, but are not executable files. The pattern matching honors the setting of the extglob shell option.

For Example:

$ EXECIGNORE=$(which pytest)

Or using Pattern Matching:

$ EXECIGNORE=*/pytest
Related Question