≡ Menu

10 Useful Linux Bash_Completion Complete Command Examples (Bash Command Line Completion on Steroids)

In Linux, while typing a command if you press TAB twice, it would list all available commands that starts with typed characters.

This is nothing new, probably you already know about this. This functionality is called bash completion. The basic file and directory name completion are available by default in bash command line.

But, we can turbo-charge this bash completion, and take it to the next level using complete command.

This tutorial explains how we can apply the auto-completion to options and to command’s arguments using programmable completion.

For example, after typing write command, if you press tab twice, auto-completion provides list of users to perform write the operation.

$ write [TAB][TAB]
bala      raj
jason     randy
john      ritu
mayla     thomas
nisha     www-data

In the following example, it would show available hostnames for the telnet command:

$ telnet [TAB][TAB]
localhost  dev-db  fileserver

To get programmable completion in your terminal, you just need to run /etc/bash_completion as shown below,

# . /etc/bash_completion

You can also uncomment the below lines in /etc/bash.bashrc(from ubuntu linux 13.04) so that you dont have to run above command explicitly,

 enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

In case if you don’t find these lines and /etc/bash_completion file, then you just need to install the package called bash_completion by apt-get

1. View Existing bash-completion

After enabling programmable bash completion, there are set of bash completion defined. The command complete is used for defining bash completion.

To view the existing bash completion, use the complete command as shown below.

 
complete -p | less

Option -p is optional in the above example.

2. List of Standard Completion in Bash

Bash provides the following standard completion for the Linux users by default.

  1. Variablename completion
  2. Username completion
  3. Hostname completion
  4. Pathname completion
  5. Filename completion

We discussed about these in our earlier bash standard completion article.

3. Define Completion for Obtaining Commands

Define a completion with -c command to get the list of available command as argument. In the following example, the completion is defined for which command,

$ complete -c which

$ which [TAB][TAB]
Display all 2116 possibilities? (y or n)

As seen above, by pressing ‘y’, all commands will get listed.

4. Define Completion for Obtaining Directories

With option d, the completion can be defined to get only directory names as argument. In the following example, defined completion for ls,

$ ls
countfiles.sh  dir1/          dir2/          dir3/

$ complete -d ls

$ ls [TAB][TAB]
dir1/          dir2/          dir3/

As seen above, pressing tab only shows you directories.

5. Define Completion for Obtaining Background Job Names

With complete, it is also possible to get job names as argument to commands. Option j is used to pass job names as argument to command job as shown below,

$ jobs
[1]-  Stopped                 cat
[2]+  Stopped                 sed 'p'

$ complete -j ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]
cat   sed

Talking about background jobs, you should also know how to manage Linux background jobs using these examples.

6. Completion with Prefix and Suffix

The completions can be defined with desired prefix to be added and suffix to be append with actual completions. In the following example, prefix and suffix is defined for list_job_attrib.sh,

$ jobs 
[1]+  Stopped                 cat

$ complete -P '">' -S '<"' ./list_job_attrib.sh

$ ./list_job_attrib.sh [TAB][TAB]

$ ./list_job_attrib.sh ">cat<"

7. Filename and Directory Completion with Exclusion

Consider that script completes its run, output got written to a output directory as follows

$ cd output/

$ ls
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt
parser_mod.tmp  extract.o

In the above, if you need to ignore the .tmp and .o files for the auto-completion with ls command then,

$ export FIGNORE='.tmp:.o'

$ complete -f -d ls

$ cd output

$ ls [TAB][TAB]
all_calls.txt   incoming_calls.txt   outgoing_calls.txt   missed_calls.txt

FIGNORE is the shell variable that contains suffix of filenames and those gets excluded in the auto-completion.

8. Split a String by IFS to get Completion Values

The wordlist can be mentioned with -W option and that gets splited with the value in IFS variable. Then each resultant word is expanded and would be displayed for completion,

$ export IFS=" "

$ complete -W "bubble quick" ./sort_numbers.sh

$ ./sort_numbers.sh [TAB][TAB]
bubble   quick

As stated above, after splited the string by IFS delimeter, the word get expanded, so its also possible to have these as variables as shown below,

$ echo $SORT_TYPE1
bubble

$ echo $SORT_TYPE2
quick

$ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh
$ ./sort_numbers.sh [TAB][TAB]
bubble   quick

9. Write Your Own Function to Generate Completion

It allows you to include a function to define completion. With -F option, the function name passed to complete command and it gets executed to generate completions. For example, the functions is written as shown below,

_parser_options()
{
  local curr_arg;

  curr_arg=${COMP_WORDS[COMP_CWORD]}

  COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) );
}

where in the above function,

  1. COMPREPLY : array holds the completion results that gets displayed after pressing [TAB][TAB]
  2. COMP_WORDS : array of words that is typed on the command line
  3. COMP_CWORD : index for the COMP_WORDS array and using this different position words on command line can be accessed.
  4. compgen : -W holds the possible completions and the respective argument get chosen based on the $current_arg

This function present in file parser_option gets sourced as shown below,

$ source parser_option

Link this function to your parser script as shown below,

$ complete -F _parser_options ./parser.pl

$ ./parser.pl [TAB][TAB]
-i       --incoming       -o       --outgoing       -m       --missed

As seen above, the options for parsers gets generated by function _parser_options().

Note : Look at /etc/bash_completion to view more functions for programmable completion.

10. Secondary Spec when Primary Doesn’t Generate Any

If there is no matches generated by the defined completion specification, then comp-option is being taken for completion mentioned with -o option.

$ complete -F _count_files -o dirnames ./countfiles.sh

As above, the completion is defined with _count_files function for file ./countfiles.sh. If the _count_files() function doesnt generate any match then directory completion gets attempted.

$ ls 
countfiles.sh    dir1/      dir2/      dir3/

$./countfiles.sh [TAB][TAB]
dir1    dir2    dir3
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Jalal Hajigholamali December 3, 2013, 3:18 am

    Hi,

    Very(very) useful article…

    Thanks a lot

  • GOWRI SANKAR December 3, 2013, 3:54 am

    Thanks Sir. Didn’t think there was more to auto completion.

  • sacarde December 3, 2013, 4:09 am

    hi,
    in archlinux I try :
    write [tab] [tab]
    or
    telnet [tab] [tab]

    but I view “display all 1445 possibilities…”

    what is wrong ?

    thank you

  • Bob December 3, 2013, 7:53 am

    Cool, thanks a lot!!!

  • Dave December 3, 2013, 9:19 am

    More precisely, “In [*bash*, and anything else that uses readline, and anything else that has implemented similar functionality] pressing while typing a command if you press TAB twice, it would list all available commands that starts with typed characters.”

    “This functionality is called [tab] completion.”

    Glad you’re exploring this, though!

  • sacarde December 4, 2013, 10:45 am

    oh.. I solve my problem

    upgrading my /etc/bash.bashrc

    thanks

  • puneeth December 9, 2013, 3:27 am

    I have a server and a telnet client, I wanted custom tab completion on the telnet client side….suppose if I issue a command like below
    telent localhost 9999
    A CLI session gets opens like below
    CLI>> (This my shell now)
    I wanted to know how to implement tab completion for this type of telnet client. or reframing, is this feature possible at all?

  • Sathish Kumar December 18, 2013, 3:58 am

    Thank you Sir!

  • Shantanu Oak December 20, 2013, 1:41 am

    Surprised to see how auto completion can be extended.
    But I prefer to disable it with switch -A while working with mysql command prompt. It improves the connection speed.

  • irfan January 1, 2014, 9:32 pm

    thank u sir.

  • paul January 23, 2014, 8:17 pm

    Oh-my-zsh. Look into it.

  • lili January 26, 2014, 2:57 am

    I like this.

  • StephaneAG December 31, 2014, 5:04 pm

    thanks for the great article !

    -> the “complete -c” comes pretty simply & is quite neat when aliasing “type” 😉

  • steven February 3, 2016, 6:43 am

    Thank you, you’re a hero!

  • Johann May 22, 2016, 11:29 pm

    It’s already all there in zsh, and as suggested above, trivially configurable through oh-my-zsh.

  • rahul June 23, 2016, 12:22 am

    Suppose I want the “foo” command to work with files that end with “.cc”.

    complete -G ‘*.cc’ foo

    Now let’s suppose my current directory contains “foo.cc”, “bar.cc”, and “blah.cc”. If I type “foo” and tab, I get:

    $ foo
    bar.cc blah.cc foo.cc
    $ foo

    which I expected. But if I type the first letter ‘b’ and try again:

    $ foo b
    bar.cc blah.cc foo.cc
    $ foo b

    It didn’t filter the results to those that start with ‘b’ as it would have, any help on this ?