Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
    
up vote 14 down vote accepted

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

#!/bin/sh

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

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.

share|improve this answer
    
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. – Stéphane Chazelas Mar 20 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.

share|improve this answer

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.)

share|improve this answer
2  
(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. – G-Man Mar 19 at 22:17
    
@G-Man : You understand that your item (2) makes this answer a precise response to the OP? – Eric Towers Mar 20 at 3:57
    
No, I don't understand that.  Please explain it to me. – G-Man Mar 20 at 4:02
    
@G-Man: OP: "Please provide me use case / practical example [for bash builtin exec]." Your comment: "the kill command has been a builtin command in bash for many years, largely because of this concern." – Eric Towers Mar 20 at 4:04
3  
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. – G-Man Mar 20 at 4:16
  • 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).

    Notes:

    • 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.
share|improve this answer
    
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. – Stéphane Chazelas Mar 20 at 10:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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