10

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?

9
  • 2
    Completion of parameters are done with functions. Most of them are set up in /etc/bash_completion.d. See also /etc/bash_completion and take a look at the output of set, how much you environment has grown.
    – ott--
    May 24, 2015 at 15:45
  • @ott What should I be looking for in that location? I unable to see anything related to sqlldr. All I have is: gdbus-bash-completion.sh gvfs-bash-completion.sh pk-completion.bash yum.bash. The output of set is just as uninteresting. May 24, 2015 at 16:13
  • It could also be done in some script from /etc/profile.d. Or maybe your .bash_profile or .bashrc was modified.
    – ott--
    May 24, 2015 at 16:21
  • How are these functions different from normal functions. And how'd I go about defining my own to provide auto complete for a custom script? Could you point in the right direction? May 24, 2015 at 16:33
  • 1
    @KshitizSharma, bash-completion loads completions dynamically since 1.90. Try: sqlldr<space><tab><enter>. Then type complete -p sqlldr.
    – Evgeny
    Jun 29, 2015 at 15:23

1 Answer 1

7

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.

2
  • yes, you can't locate where complete was called. But you can find the source file name and line number where the completion function is defined. complete -p sudo # outputs complete -F _sudo sudo, shopt -s extdebug, declare -F _sudo # outputs _sudo 3 /usr/share/bash-completion/completions/sudo. (But see my comment about dynamically completions loading and complete -p).
    – Evgeny
    Jun 29, 2015 at 16:23
  • and the settings for the basename of the command are applied. No. You can have a different compspecs for date and /bin/date. Reference says: If the command word is a full pathname, a compspec for the full pathname is searched for first. If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash
    – Evgeny
    Jun 30, 2015 at 3:17

You must log in to answer this question.

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