UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 8.10 eval: When You Need Another Chance Chapter 8
How the Shell Interprets What You Type
Next: 8.12 Which One Will the C Shell Use?
 

8.11 Which One Will bash Use?

Article 8.5 gives an general overview of what the C shell does as it evaluates a command line. bash does something similar. This article takes a closer look at how you can control one part of those steps: whether bash will choose a shell function, a built-in command, or an external command. (If you're interested in a detailed and humorous look at the way this is handled in the C shell, read article 8.12.)

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. 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? (Same question 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 only execute 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 (6.4)) 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 by typing its absolute pathname. For example, when I was revising article 8.20, I wanted to test the 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 for article 8.20, 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 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


Previous: 8.10 eval: When You Need Another Chance UNIX Power ToolsNext: 8.12 Which One Will the C Shell Use?
8.10 eval: When You Need Another Chance Book Index8.12 Which One Will the C Shell Use?

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System