27.9. Which One Will bash Use?
bash, like
all shells, performs a series of steps when evaluating a command
line. (Sorry, we don't cover all of the Unix shells;
we explain bash because it's one
of the most common. For other shells, check their manual pages.) This
article takes a closer look at how you can control one part of those
steps in bash: whether the shell will choose
a
shell function (Section 29.11), a built-in
command ( Section 1.9), or an
external command (Section 1.9).
Let's say that you want to write shell functions
named cd, pushd, and
popd. They will run the shell's
built-in cd, pushd, or
popd command, respectively, each using the
command-line arguments that were passed (via the
$@ array reference). Next they execute another
shell function named setvars to do some setup in
the new directory:
cd( ) { pushd( ) { popd( ) {
cd "$@" pushd "$@" popd "$@"
setvars setvars setvars
} } }
But which cd will bash use when
you type cd: the built-in cd or
your cd function? (The same question goes for
pushd and popd.) Worse, what if
the cd <">$@<"> command inside the
function makes bash call your
cd function again, and that starts an
endless loop? Well, that
actually will start a loop -- and you need to
know how to prevent it.
Typing
command before the name of a command disables
shell function lookup. bash will execute only a
built-in command or an external command with that name. So, you could
keep the functions from re-executing themselves by defining them this
way:
cd( ) { pushd( ) { popd( ) {
command cd "$@" command pushd "$@" command popd "$@"
setvars setvars setvars
} } }
In the same way, if you don't want to run your new
pushd function for some reason,
here's how to use the built-in
pushd once:
bash$ command pushd somewhere
The command command still allows
bash to run an external command (from your
PATH (Section 35.6))
with the name you give. To force bash to use a
built-in command -- but not a shell function or an external
command -- type
builtin before the command name. Although
bash will always choose a built-in command before
an external command, you can specify the built-in
echo unambiguously with:
builtin echo -n 'What next? '
What if you want the external
echo command? The easiest way is probably to type
its absolute pathname. For example, once I wanted to test four (!)
different external versions of echo on a System V
machine -- and not get the built-in bash
version. So I typed commands like this:
bash$ /bin/echo hi \\ there
Finally, you
can enable or disable specific built-in bash
commands with the enable command. Unlike
command and builtin, the effect
of enable lasts until you exit the shell. The
command enable -n disables one or more
built-in commands; give the command names as arguments. For example,
in my experiments mentioned above, I could have made sure that
I'd get an external echo every
time by typing this first command once:
bash$ enable -n echo
bash$ type echo
echo is hashed (/bin/echo)
The
-n disables the built-in command named as the
following argument. The bash
type command confirms that I'll
now be using the external echo. You can re-enable
a disabled built-in with enable
command-name. And enable
-a lists the status of all bash
built-ins.
-- JP
 |  |  | 27.8. eval: When You Need Another Chance |  | 27.10. Which One Will the C Shell Use? |
Copyright © 2003 O'Reilly & Associates. All rights reserved.
|