Advertisement
Advertisement


What are the uses of the exec command in shell scripts?


Question

Can anyone explain what are the uses of the exec command in shell scripting with simple examples?

2014/11/24
1
254
11/24/2014 4:51:00 PM

Accepted Answer

The exec built-in command mirrors functions in the kernel, there are a family of them based on execve, which is usually called from C.

exec replaces the current program in the current process, without forking a new process. It is not something you would use in every script you write, but it comes in handy on occasion. Here are some scenarios I have used it;

  1. We want the user to run a specific application program without access to the shell. We could change the sign-in program in /etc/passwd, but maybe we want environment setting to be used from start-up files. So, in (say) .profile, the last statement says something like:

     exec appln-program
    

    so now there is no shell to go back to. Even if appln-program crashes, the end-user cannot get to a shell, because it is not there - the exec replaced it.

  2. We want to use a different shell to the one in /etc/passwd. Stupid as it may seem, some sites do not allow users to alter their sign-in shell. One site I know had everyone start with csh, and everyone just put into their .login (csh start-up file) a call to ksh. While that worked, it left a stray csh process running, and the logout was two stage which could get confusing. So we changed it to exec ksh which just replaced the c-shell program with the korn shell, and made everything simpler (there are other issues with this, such as the fact that the ksh is not a login-shell).

  3. Just to save processes. If we call prog1 -> prog2 -> prog3 -> prog4 etc. and never go back, then make each call an exec. It saves resources (not much, admittedly, unless repeated) and makes shutdown simplier.

You have obviously seen exec used somewhere, perhaps if you showed the code that's bugging you we could justify its use.

Edit: I realised that my answer above is incomplete. There are two uses of exec in shells like ksh and bash - used for opening file descriptors. Here are some examples:

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Note that spacing is very important here. If you place a space between the fd number and the redirection symbol then exec reverts to the original meaning:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

There are several ways you can use these, on ksh use read -u or print -u, on bash, for example:

read <&3
echo stuff >&4
2017/03/19
283
3/19/2017 8:40:38 PM

Just to augment the accepted answer with a brief newbie-friendly short answer, you probably don't need exec.

If you're still here, the following discussion should hopefully reveal why. When you run, say,

sh -c 'command'

you run a sh instance, then start command as a child of that sh instance. When command finishes, the sh instance also finishes.

sh -c 'exec command'

runs a sh instance, then replaces that sh instance with the command binary, and runs that instead.

Of course, both of these are useless in this limited context; you simply want

command

There are some fringe situations where you want the shell to read its configuration file or somehow otherwise set up the environment as a preparation for running command. This is pretty much the sole situation where exec command is useful.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

This does some stuff to prepare the environment so that it contains what is needed. Once that's done, the sh instance is no longer necessary, and so it's a (minor) optimization to simply replace the sh instance with the command process, rather than have sh run it as a child process and wait for it, then exit as soon as it finishes.

Similarly, if you want to free up as much resources as possible for a heavyish command at the end of a shell script, you might want to exec that command as an optimization.

If something forces you to run sh but you really wanted to run something else, exec something else is of course a workaround to replace the undesired sh instance (like for example if you really wanted to run your own spiffy gosh instead of sh but yours isn't listed in /etc/shells so you can't specify it as your login shell).

The second use of exec to manipulate file descriptors is a separate topic. The accepted answer covers that nicely; to keep this self-contained, I'll just defer to the manual for anything where exec is followed by a redirect instead of a command name.

2016/07/26