Consider this from the documentation of Bash' builtin exec:

exec replaces the shell without creating a new process

Please provide a use case / practical example. I don’t understand how this makes sense.

I googled and found about I/O redirection. Can you explain it better?


exec is often used in shell scripts which mainly act as wrappers for starting other binaries. For example:


if stuff;
    EXTRA_OPTIONS="-x -y -z"
    EXTRA_OPTIONS="-a foo"

exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"

so that after the wrapper is finished running, the "real" binary takes over and there is no longer any trace of the wrapper script that temporarily occupied the same slot in the process table. The "real" binary is a direct child of whatever launched it instead of a grandchild.

You mention also I/O redirection in your question. That is quite a different use case of exec and has nothing to do with replacing the shell with another process. When exec has no arguments, like so:

exec 3>>/tmp/logfile

then I/O redirections on the command line take effect in the current shell process, but the current shell process keeps running and moves on to the next command in the script.

  • 1
    You may say that the two cases are related in that for both, exec tells the shell not to do the action (execute a command or perform a redirection) in a child process, but in the same process. Mar 20 '16 at 7:55

I've used a shell exec builtin to get a process ID (PID) to a Java program. There may be a way to get PID from inside Java now, but several years ago, there was not. Once a process has its own PID, it can write that out to a PID file (look in /var/run/ for file names with a '.pid' suffix) to allow management programs to know the PID of the running process, and to prevent a second instance of the same server from running. It works something like this:

exec java -cp=YourServer.jar StartClass -p $$

Code in the main() method of class StartClass handles argument parsing and can find its own process ID.


For fun, run the following program (translated to your implementation language of choice) in the background on a system with user process accounting and limits.

while(true) fork();

Now that every slot in the process table that you are permitted to use is full of copies of that running program, how do you intend to kill it? Launching kill(1) requires another process slot, which you can't have. It sure would be handy to have the shell replace itself with the kill command...

exec /bin/kill -9 -1

(Assumes your system has kill(1) at /bin/kill. "exec `which kill` -9 -1" is potentially safer.) This sends SIGKILL to every process you can.

(Note: Don't log out from your launching shell unless the process limits always permit a new login a process slot for its shell. This can be a bit more difficult to clean up if you do. I certainly did not do this in the early '90s. Nope.)

  • 3
    (1) This answer would be slightly better if you actually showed the exec command that would be useful in this situation. (2) This answer is somewhat archaic; the kill command has been a builtin command in bash for many years, largely because of this concern. Mar 19 '16 at 22:17
  • @G-Man : You understand that your item (2) makes this answer a precise response to the OP? Mar 20 '16 at 3:57
  • No, I don't understand that.  Please explain it to me. Mar 20 '16 at 4:02
  • 4
    I'm not following you.  The question doesn't ask for practical examples of all bash builtin commands; it asks for examples of exec — and the fact that kill is a builtin doesn't really have anything to do with the exec builtin. Mar 20 '16 at 4:16
  • 1
    I just read your update to your answer. (1) Guess what?  If the process table is full, then command substitution (e.g., `which kill`) isn’t going to work either. (2) BTW, the $(…) form is recommended over the `…` form. (3) But there’s nothing dangerous about guessing at the directory.  If you accidentally type exec /binn/kill, you’ll simply get an error message, and your shell won’t go away. (4) But you don’t even need to worry about what directory kill is in.  exec uses $PATH, just like normal commands, so exec kill … works (assuming you have /bin in your search path). Mar 20 '16 at 5:10
  • This is similar to Bruce’s example of needing to know the PID of a process:

    ( cmdpid=$BASHPID; (sleep 300; kill "$cmdpid") & exec long-running-command )

    in which you

    1. Start a subshell (the outer ( and )),
    2. Find out the PID of the subshell.  ($$ will give you the PID of the main shell.)
    3. Detach a sub-subshell that kills your process after a timeout, and
    4. Run a command in the process of the subshell that you created in step 1.

    This will run long-running-command, but only for a pre-determined, limited amount of time. 

  • This is a little frivolous, but, if you decide that you want to be root (or some other user) for the rest of your login session, you could exec su.

    Actually, I can imagine a scenario where this would really be useful.  Suppose that you’re logged in to a remote system, and, for some reason, there’s a problem with breaking the connection and starting a new connection.  For example, suppose the remote system has a firewall that follows a schedule.  You were allowed to connect when you did, and established connections don’t get closed, but at the current time, new connections are not being accepted.

    You’ve done what you wanted to do, and you’re ready to logout.  Your friend Bob is in the room with you, and he wants to do some work on the remote system — but he won’t be able to connect.  So, you type exec su - bob, and, when the password prompt appears, turn the workstation over to him.  There is now no process with your UID (unless you ran something in the background), so Bob won’t be able to mess around with your files.  He will have effectively taken over your connection (with your consent and cooperation).


    • Of course this won’t work if you aren’t allowed to run su.
    • It will get logged, so you may need to explain your motives to somebody.  Since you are circumventing policy (the firewall schedule), you might get into trouble.
    • I don’t guarantee that it is 100% secure.  For example, who will probably still show your name.  It’s conceivable that some (badly written) program will use that to think that Bob is you, and give him access to your resources.
    • If the system does auditing, Bob’s actions might be audited under your name.
  • Note that in practice in most shells, (a;b) is already the same as (a;exec b) as shells optimize out the fork for the last command in a subshell. The only exceptions seem to be bash and mksh. Using exec helps to guarantee it. Mar 20 '16 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.