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.Variablename completion
Username completion
Hostname completion
Pathname completion
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 [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,COMPREPLY : array holds the completion results that gets displayed after pressing [TAB][TAB]
COMP_WORDS : array of words that is typed on the command line
COMP_CWORD : index for the COMP_WORDS array and using this different position words on command line can be accessed.
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