Command line expansion

When you enter a command on the command line and press enter, the command interpreter performs several actions before executing the command.

History expansion - the line is analysed for history references or the bang !. These are replaced by the appropriate strings from history list.

History list updated - the new command line is stored in the history list. Note that no other command line expansion or parsing is done at this point.

Alias replacement - next any alias references are replaced with their definition.

The shell then begins a series of expansions of the command line up to a recognized delimiter, the end of line, a semi-colon, pipe, &&, ||, or &. This is also the point at which redirection is noted.

Brace expansion - expand any list inside of braces. {dog,bird}house

Tilde expansion - ~ represents the user's home directory. If a user id follows the tilde, then it will be the home directory of that user. If it is ~+, the shell will use the contents of PWD (current directory). And if it is ~-, the shell will use the contents of OPWD (last directory).

Parameter expansion - expand parameters such as the $1-9, $*, $$, etc. This also where variables are substituted. The bash shell also offers conditional expansion when you combine $ with the {} characters. See parameter expansion section in the bash man page.

Command substitution - run the command specified and paste its output in the command buffer. You may use either ` ` or $( ) to specify command substitution.

Arithmetic expansion - bash provides its own arithmetic evaluation mechanism in place of running the expr command. To use arthmetic expansion, enclose the formula in $(( )).

echo $(( 4 + 3 ))

If you work mostly in the bash shell, this is more efficient than invoking the
expr command each time. On the other hand, if you work in several shells, using expr will provide a more consistant programming practice.

Word splitting - at this point, separation of unquoted strings is recognized. Word splitting works with the IFS (internal field separator) variable to determine how a string is to be parsed. The IFS affects how the read command handles input and how $* and $@ and some of the other parameter referecnes are expanded.

#( Try the following )

#( Start a new copy of the bash shell. If you hav trouble resetting the IFS variable, you can terminate the child shell. )

bash

read v1 v2
#(When prompted, enter the following)

one:two three

echo $v1
echo $v2

#(Display the current contents of the IFS variable )
echo "$IFS" | cat -vet

#( Reset IFS to use : as a delimiter )
IFS=:

read v1 v2
#(When prompted, enter the following)

one:two three

echo $v1
echo $v2

#(You should now see the input split at the : rather than the space )

#(To reset IFS, use IFS="[space][ctrl]v[tab][enter]" )

#(To test IFS, Display its current contents )
echo "$IFS" | cat -vet

#( Quit the child shell )
exit

Pathname expansion (filename wildcards) - expand the filename wildcards.

Quote Removal - Any unquoted occurences of \, ', and " that did not result from a previous expansion are now removed.

In most cases, entering a command on the command line will be straight forward. Occasionally, you will need to build a command that requires several diffferent expansions and knowing the order of expansion will help in its implementation.


eval - evaluate a command sequence.

eval invokes a set of arguments as a command sequence. It is useful when you need the arguments to be expanded twice.

#( Try the following )

var=value

#( Set teh variable cmd to hold a command to run later)
echo -e "Enter a command to run \c"; read cmd

#( When prompted, enter  echo $var )
echo $var

#( Now reference the variable at the prompt and press [enter])
$var

#( The echo will run but it will print out $var)
#( Repeat this, except use eval to run it )
eval $var

#( Now the contents of var will be printed )

At the prompt, we could have just assigned the echo $var to an alias. However, in a bash shell script, aliases don't exist. The eval allows you to work around this limitation. eval is available in most other shells.


We have looked at how a command is processed in preparation for execution. We will now look at how a command is actually executed.

Executing a program