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.
-
Redirecting
stdout
-exec 1>file
will cause the standard output to be a file namedfile
for the end of the current shell session. Anything to output to the display will be in the file. -
Redirecting
stdin
- It can also be used to redirect thestdin
to a file. For example, If you want to execute a script filescript.sh
, you can just redirect thestdin
to the file usingexec 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.