What are possible use of exec command?

I am learning exec command. I know that the exec command replaces the process which has started it. So that isn't possible to return to the process which is replaced by exec command.

One could say that it's purpose is to make it impossible to return to the process which started it.

But what are other uses for having something like exec available as a command?


The exec command replaces the current shell process with the specified command. Normally, when you run a command a new process is spawned (forked). The exec command does not spawn a new process. Instead, the current process is overlaid with the new command. In other words the exec command is executed in place of the current shell without creating a new process.

There are three most common uses of exec command:

1. Replacement of process

Example-1: If you open a new bash shell as

$ bash 

in pstree it looks like

├─gnome-terminal
        ├─bash───bash───pstree

The previous bash shell is still there and you got a new bash shell. Whereas if you open a new bash shell as,

$ exec bash

the pstree shows

├─gnome-terminal
        ├─bash───pstree

Here the old bash is replaced with new one. It is particularly useful to exit from multiple login in one command. It is more secure and eradicates the chance of leaving an open terminal by mistake. See Exit from both root and user with one command

Example-2: you can open a file as

$ exec vi filename.txt

When you quit vi there is no need to close the terminal separately as the shell is already replaced. As soon as you close the vi the terminal is also closed.

2. A method of redirection of file descriptors within the shell scripts

The exec command can also be used in shell scripts dynamically open, close, and copy file descriptors. That permits performing redirection of STDIN, STDERR, STDOUT and other file descriptors to various files inside the shell script, instead of command invocation string. If you do not specify a command or arguments, you can specify redirection symbols and file descriptors to perform these functions.

Say you have a shell script script.sh you want to have a log file script.log, you can use exec as,

LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1

which is equivalent to

./script &>> /path/to/script.log
./script >>  /path/to/script.log 2>&1

3. Creating stages of the process using exec command

You can also use the exec command to create a set of shell scripts that execute one another sequentially like stages of the process. Instead of spawning new processes each time you need to transfer the control to the next script you execute the exec command .

In this case the last statement of each stage should be exec command that invokes the next stage.

See the uses of the exec command in shell scripts for more.

Note: Part of above is taken from this.


In wrapper script

exec is used mainly in wrapper scripts.

If you want to modify the environment for a program before executing the main program, you'd often write an script and at the end of it start the main program. But there is no need for the script to stay in memory at that time. So, exec is used in these cases so that, the main program can replace the mother script.

Here is a practical example of it. It's mate-terminal.wrapper script comes with mate-terminal. It starts the mate-terminal with some extra arguments by checking user's environments.

#!/usr/bin/perl -w

my $login=0;

while ($opt = shift(@ARGV))
{
    if ($opt eq '-display')
    {
        $ENV{'DISPLAY'} = shift(@ARGV);
    }
    elsif ($opt eq '-name')
    {
        $arg = shift(@ARGV);
        push(@args, "--window-with-profile=$arg");
    }
    elsif ($opt eq '-n')
    {
        # Accept but ignore
        print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
    }
    elsif ($opt eq '-T' || $opt eq '-title')
    {
        push(@args, '-t', shift(@ARGV));
    }
    elsif ($opt eq '-ls')
    {
        $login = 1;
    }
    elsif ($opt eq '+ls')
    {
        $login = 0;
    }
    elsif ($opt eq '-geometry')
    {
        $arg = shift(@ARGV);
        push(@args, "--geometry=$arg");
    }
    elsif ($opt eq '-fn')
    {
        $arg = shift(@ARGV);
        push(@args, "--font=$arg");
    }
    elsif ($opt eq '-fg')
    {
        $arg = shift(@ARGV);
        push(@args, "--foreground=$arg");
    }
    elsif ($opt eq '-bg')
    {
        $arg = shift(@ARGV);
        push(@args, "--background=$arg");
    }
    elsif ($opt eq '-tn')
    {
       $arg = shift(@ARGV);
       push(@args, "--termname=$arg");
    }
    elsif ($opt eq '-e')
    {
        $arg = shift(@ARGV);
        if (@ARGV)
        {
            push(@args, '-x', $arg, @ARGV);
            last;
        }
        else
        {
            push(@args, '-e', $arg);
        }
        last;
    }
    elsif ($opt eq '-h' || $opt eq '--help')
    {
        push(@args, '--help');
    }
}
if ($login == 1)
{
    @args = ('--login', @args);
}
exec('mate-terminal',@args);

The point to notice here is, there is an exec call, which replaces this script in memory.

Here is a similar question answered in Unix & Linux StackExchange Site - https://unix.stackexchange.com/q/270929/19288

To redirect file-descriptors

Another common use of exec is in redirecting file-descriptors. stdin, stdout, stderr can be redirected to files using exec.

  1. Redirecting stdout - exec 1>file will cause the standard output to be a file named file for the end of the current shell session. Anything to output to the display will be in the file.

  2. Redirecting stdin - It can also be used to redirect the stdin to a file. For example, If you want to execute a script file script.sh, you can just redirect the stdin to the file using exec 0<script.sh.


As far as i know it is also used to redirect file descriptors (for example, STDOUT, STDERR, STDIN) of a bash-script.

So for example, you could read from a file instead from the keyboard by using STDIN redirection and write to a file instead of the terminal by STDOUT (or could be STDERR depending on program) redirection.