mirror of https://github.com/tLDP/LDP
166 lines
6.6 KiB
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>
|
|
|