LDP/LDP/guide/docbook/abs-guide/TABEXP.xml

166 lines
6.6 KiB
XML

<title>An Introduction to Programmable Completion</title>
<para>The <firstterm>programmable completion</firstterm> feature in
Bash permits typing a partial command, then pressing the
<keycap>[Tab]</keycap> key to auto-complete the command sequence.
<footnote><para>This works only from the <firstterm>command
line</firstterm>, of course, and not within a
script.</para></footnote>
If multiple completions are possible, then <keycap>[Tab]</keycap>
lists them all. Let's see how it works.</para>
<para>
<screen>
<prompt>bash$ </prompt><userinput>xtra[Tab]</userinput>
<computeroutput>xtraceroute xtrapin xtrapproto
xtraceroute.real xtrapinfo xtrapreset
xtrapchar xtrapout xtrapstats</computeroutput>
<prompt>bash$ </prompt><userinput>xtrac[Tab]</userinput>
<computeroutput>xtraceroute xtraceroute.real</computeroutput>
<prompt>bash$ </prompt><userinput>xtraceroute.r[Tab]</userinput>
<computeroutput>xtraceroute.real</computeroutput>
</screen>
</para>
<para>Tab completion also works for variables and path names.</para>
<para>
<screen>
<prompt>bash$ </prompt><userinput>echo $BASH[Tab]</userinput>
<computeroutput>$BASH $BASH_COMPLETION $BASH_SUBSHELL
$BASH_ARGC $BASH_COMPLETION_DIR $BASH_VERSINFO
$BASH_ARGV $BASH_LINENO $BASH_VERSION
$BASH_COMMAND $BASH_SOURCE</computeroutput>
<prompt>bash$ </prompt><userinput>echo /usr/local/[Tab]</userinput>
<computeroutput>bin/ etc/ include/ libexec/ sbin/ src/
doc/ games/ lib/ man/ share/</computeroutput>
</screen>
</para>
<para><anchor id="completeref"/></para>
<para>The Bash <command>complete</command> and
<command>compgen</command> <link
linkend="builtinref">builtins</link> make it
possible for <firstterm>tab completion</firstterm> to
recognize partial <firstterm>parameters</firstterm> and
<firstterm>options</firstterm> to commands. In a very simple case,
we can use <command>complete</command> from the command-line to
specify a short list of acceptable parameters.</para>
<screen>
<prompt>bash$ </prompt><userinput>touch sample_command</userinput>
<prompt>bash$ </prompt><userinput>touch file1.txt file2.txt file2.doc file30.txt file4.zzz</userinput>
<prompt>bash$ </prompt><userinput>chmod +x sample_command</userinput>
<prompt>bash$ </prompt><userinput>complete -f -X '!*.txt' sample_command</userinput>
<prompt>bash$ </prompt><userinput>./sample[Tab][Tab]</userinput>
<computeroutput>sample_command</computeroutput>
<computeroutput>file1.txt file2.txt file30.txt</computeroutput>
</screen>
<para>The <option>-f</option> option to
<firstterm>complete</firstterm> specifies filenames,
and <option>-X</option> the filter pattern.</para>
<para><anchor id="compgenref"/></para>
<para>For anything more complex, we could write a script that
specifies a list of acceptable command-line parameters.
The <command>compgen</command> builtin expands a list of
<firstterm>arguments</firstterm> to <firstterm>generate</firstterm>
completion matches. </para>
<para>Let us take a <link linkend="usegetopt2">modified version</link>
of the <emphasis>UseGetOpt.sh</emphasis> script as an example
command. This script accepts a number of command-line parameters,
preceded by either a single or double dash. And here is the
corresponding <firstterm>completion script</firstterm>, by
convention given a filename corresponding to its associated
command.</para>
<example id="usegetoptex">
<title>Completion script for
<firstterm>UseGetOpt.sh</firstterm></title>
<programlisting>&usegetoptex;</programlisting>
</example>
<para>Now, let's try it.</para>
<screen>
<prompt>bash$ </prompt><userinput>source UseGetOpt-2</userinput>
<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh -[Tab]</userinput>
<computeroutput>-- --aoption --debug --file --help --log --test
-a -d -f -h -l -t</computeroutput>
<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh --[Tab]</userinput>
<computeroutput>-- --aoption --debug --file --help --log --test</computeroutput>
</screen>
<para>
We begin by <link linkend="sourceref">sourcing</link> the <quote>completion
script.</quote> This sets the command-line parameters.
<footnote><para>Normally the default parameter completion files reside
in either the <filename class="directory">/etc/profile.d</filename>
directory or in <filename
class="directory">/etc/bash_completion</filename>. These autoload on
system startup. So, after writing a useful completion script, you
might wish to move it (as <firstterm>root</firstterm>, of course)
to one of these directories.</para></footnote>
</para>
<para>In the first instance, hitting <keycap>[Tab]</keycap> after
a single dash, the output is all the possible parameters preceded by
<emphasis>one or more</emphasis> dashes. Hitting <keycap>[Tab]</keycap>
after <emphasis>two</emphasis> dashes gives the possible parameters
preceded by <emphasis>two or more</emphasis> dashes.</para>
<para>Now, just what is the point of having to jump through flaming
hoops to enable command-line tab completion? <emphasis>It saves
keystrokes.</emphasis>
<footnote><para>It has been extensively documented that
programmers are willing to put in long hours of effort in
order to save ten minutes of <quote>unnecessary</quote>
labor. This is known as
<firstterm>optimization</firstterm>.</para></footnote>
</para>
<para>--</para>
<para><emphasis>Resources:</emphasis></para>
<para>Bash <ulink url="http://freshmeat.net/projects/bashcompletion">
programmable completion</ulink> project</para>
<para>Mitch Frazier's <ulink
url="http://www.linuxjournal.com"><citetitle
pubwork="journal">Linux Journal</citetitle></ulink> article, <ulink
url="http://www.linuxjournal.com/content/more-using-bash-complete-command"><emphasis>More
on Using the Bash Complete Command</emphasis></ulink></para>
<para>Steve's excellent two-part article, <quote>An Introduction to Bash
Completion</quote>:
<ulink
url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_1">Part
1</ulink> and
<ulink url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2">Part 2</ulink></para>