Chapter 12. Bits and pieces - tying up the loose ends

Table of Contents

The eval command
Running commands in the background using &
Traps and signals
Signals
Traps
Exercises:
File descriptors re-visited
Exercises
Here documents
Exercises
Functions
Exercises:
Challenge sequence

The eval command

Let's start with the eval command. If we type:

ls |wc -l
            

This will pipe your ls output to the word count command. What happens if you say:

PIPE='|'
ls $PIPE wc -l
            

We now have set a variable PIPE to the pipe character.

The command will not execute the way you would expect it to. The first thing that happens, is that the $PIPE is replaced by the pipe character, then the shell will execute the command ls but will then croak, saying there is no such command called '|', or 'wc'.

Why? The shell does the variable expansion first if you remember, then it tries to run the command ls, looking for a file called '|', and one called 'wc'.

Clearly, there are not files by these names in our home directory and so the message "No such file or directory" is returned by the shell.

Somehow we need to be able to re-evaluate this command line after the variable expansion has taken place.

That's not too difficult if we make use of the eval command as follows:

eval ls $PIPE wc -l 
            

The eval command re-reads the command line. So once the substitution of the variable has taken place (i.e. $PIPE has been translated into a vertical bar), eval then rereads that command and voila, success!

Let's take a look at another couple of examples:

Let's assume I have the commands, stored in a variable:

cmd='cat file* | sort'
            

Now comes the time I need them, so I try:

$cmd
            

This only half works, but had I done:

eval $cmd
            

It would have worked like a dream, because the eval would have re-evaluated the command line AFTER the variable substitution had been done.

x=100
ptr=x
            

Now, type:

echo \${$ptr}
            

Remember $$ is your process id, so you must enclose $ptr in curly braces. You also need to escape the first dollar, because you want eval to see a literal $. This would produce:

$x
            

But the problem persists; we will end up with $x on the command line. Not quite what we had in mind, so we'd have to:

eval echo \${$ptr}
            

which would give us the desired output:

100
            

We are almost executing a second level of variable substitution and eval is the command that allows us to do that. While this command is used infrequently, you will certainly benefit from knowing it's around when you really need it!