Bash – How Does Bash Auto Completion Work?

autocompletebash

I can understand that bash auto completion works for standard utilities. But how does it do auto completion for custom programs like Oracle SQL loader?

In the following command if you Tab after control= then it autocompletes to the control file name:

sqlldr kshitiz/oracle@XE control=data.ctl data=data.csv bad=data.bad log=data.log

How does it know it has to fill in the control file at that point and not some other file?

Best Answer

Bash's programmable completion works by parsing the command line and figuring out what is being completed:

  1. Some contexts are treated specially, e.g. the first word in a command is completed as a command name, what follows a $ is completed as a variable name, etc.
  2. Outside of these contexts, bash attempts to complete the argument of a command, and the settings for command or failing that (which is usually the case) for the basename of the command are applied.

For example, after sqllTab, bash completes command names that start with sqll. After sqlldr $aTab, bash completes variable names that start with a. After sqlldr Tab, bash applies the completion rules for the command sqlldr. Completion rules can specify a category (user, variable, files, etc.), a wildcard pattern for file names, or a function or code snippet to execute.

Completion rules are defined by the complete builtin. Bash doesn't keep track of when the complete builtin was called or what script (if any) it was in. Most distributions ship the bash-completion package, which provides a series of rules for common commands. This takes the form of a series of script files that contain calls to complete, with a script that must be read from .bashrc (or /etc/bash.bashrc if implemented) to load all of these scripts: typically . /etc/bash_completion is needed to activate programmable completion and load the available scripts.

The standard package does not include support for sqlldr. If you have such support, it must be coming from a different source. This source might have dropped a file in a directory like /etc/bash_completion.d or might have come with instructions to include some code in your .bashrc. You can use complete -p sqlldr to see the current rules for sqlldr; as mentioned before, this won't tell you where those rules were loaded from.

Tcsh, zsh and fish have somewhat similar mechanisms (everybody got their inspiration from tcsh) but different builtins, syntaxes and capabilities.

Related Question