Main index

Introducing UNIX and Linux


Advanced shell programming

Overview
Sending and trapping signals
      Signal names
Functions
Aliases
The 'exec' mechanism
The 'eval' mechanism
Sending data across networks
      Sending printable characters
      Splitting files
Makefiles
Safe programming
Setting up a terminal
More on files
Miscellaneous utilities
Summary
Exercises

The 'exec' mechanism

When you execute a script, a copy of the shell is created. Thus when that script itself executes a command, a process is created for that command as well as the process for the calling shell. This is potentially inefficient, especially if the script is relatively simple, but essentially unavoidable. In a few instances, however, the calling shell is redundant, in particular if a utility is executed as the last command in the shell. The shell will terminate precisely when the utility has terminated. During the time that the utility is running, the shell's process continues to run, but is simply waiting for the utility to finish - nothing more. This is inefficient because the kernel still needs to manage the shell process, and the shell is a 'big' program. The command exec is provided to reduce this redundancy. Using exec the final command can be executed by the same process as the calling shell. UNIX accomplishes this by replacing the machine code the shell process contains with the machine code for the command, and the shell cannot therefore execute any later commands. Suppose file sleepfile contains one line sleep 100:

sh sleepfile &
[1] 28409
ps
  PID TT STAT  TIME COMMAND
15826 p4 S     0:21 sh
28409 p4 S     0:00 sh sleepfile
28410 p4 S     0:00 sleep 100
28417 p4 R     0:00 ps

There are 4 processes, your login shell 15826, the ps process, process 28409 for the shell that interprets the script, and the process 28410 for the command in the script. Now, replace the first line of the file by exec sleep 100, and we get:

sh sleepfile &
[1] 28547
ps
  PID TT STAT  TIME COMMAND
15826 p4 S     0:22 sh
28547 p4 S     0:00 sleep 100
28551 p4 R     0:00 ps

The shell script was created with PID 28547. When we look at the processes, we have the login shell and the ps process as before, but process 28547 is the sleep command, not a shell.

Worked example

Write a script to take one argument, assumed to be a filename, and run vi on that file using exec. If no arguments are given, the script should exit with return status 1.
Solution:

# Check number of arguments
if [ $# -ne 1 ]

# If too few arguments, warn user
then  echo $0 requires exactly 1 argument
      # and exit with status 1
      exit 1
# otherwise run vi
else  exec vi $1
fi

Copyright © 2002 Mike Joy, Stephen Jarvis and Michael Luck