|
Softpanorama |
May the source be with you, but remember the KISS principle ;-)
Softpanorama Search
|
| News | Books | See also | Recommended Links | Examples |
Additional Examples |
|
| Shells | Pipes | AWK | Perl | grep | find | Regex |
| sort | uniq | cut | tee | History | Humor | Etc |
The internal exec command replaces the current shell process with the specified command. Normally, when you run a command a new process is spawned. The exec command does not spawn a new process. Instead, the current process is overlaid with the new command. In other words ehe exec command is executed in place of the current shell without creating a new process. Input/output arguments may appear and, if no other arguments are given, it cause the shell input/output to be modified. The name of the command is identical to the name of system call that provide semantic of this command in Unix.
The most common usage of command is the replacement of login shell when the shell in /etc/passwd is not that you want and you have no power to change the setting:
exec bash
The exec command is useful in pipes and can be used to set redirection file descriptors. In the latter case the current shell process is modified but not overlaid. In shell the exec command can be used to open, close, and copy file descriptors. If you do not specify a command or arguments, you can specify redirection symbols and file descriptors to perform these functions.
If you specify a command, the shell replaces itself in memory with the new command you specified. For example,
exec vi myfile
replaces the shell with the vi program text and places you in vi, editing myfile. When you exit vi you exit the system because vi has become your login interface to the operating system.
You can also use the exec command in a set of shell scripts that execute one another. Instead of spawning new processes each time you call a different script, you can exec to the new shell.
The exec command may also be used to open, close, and copy file descriptors as specified by I/O redirection.
You can use exec to perform I/O redirection commands. The following examples illustrate the use of exec for manipulating file descriptors:
exec 3< inputfile # Opens inputfile with file descriptor 3 for reading. exec 4> outputfile # Opens outputfile with file descriptor 4 for writing. exec 5<&0 # Makes fd 5 a copy of fd 0 (standard input). exec 6>&p # Attach fd 6 to co-process.
Following is the general format of the exec command.
exec [ command ] [ arg ... ]
exec fd< file
exec fd> file
Arguments
| command | An executable command. The command replaces the current shell in memory without spawning a new process. If you cannot execute the command for some reason, then you exit the current shell. |
| arg | Arguments to command. |
| fd< file | Opens file for input with file descriptor fd. |
| fd> file | Opens file for output with file descriptor fd. |
while true
do
echo "Go to Mail, Editor, or eXit:"
read ANS
case "$ANS" in
[mM]) exec MAILX ;;
[eE]) exec ${EDITOR:=vi} ;;
[xX]) ezec exit ;;
esac
done
|
|||||||
As Sys Admin contributing editors, we've had the opportunity to answer a number of novice shell questions. In this column, we'll cover a few of the questions we've been asked:
Using the exec & eval Commands
- Using the exec and eval commands
- Combining files using the paste command
- Processing a string a character at a time
- Deleting a file named dash
One novice asked when it was suitable to exec and eval Unix commands:
exec mycommand eval mycommandThe exec command works differently depending on the shell; in the Bourne and Korn shells, the exec command replaces the current shell with the command being exec'ed. Consider this stub script:exec echo "Hello John" echo "Hello Ed" # end stubWhen the above stub executes, the current shell will be replaced when exec'ing the echo "Hello John" command. The echo "Hello Ed" command never gets the chance to execute. Obviously, this capability has limited uses.You might design a shell menu where the requirement is to execute an option that never returns to the menu. Another use would be restricting the user from obtaining the command line. The following last line in the user's .profile file logs the user out as soon as my_executable terminates:
exec my_executableHowever, most systems administrators probably use the exit command instead:my_executable exitDon't confuse exec'ing a Unix command with using exec to assign a file to a file descriptor. Remember that the default descriptors are standard input, output, and error or 0, 1, and 2, respectively.Let's consider an example where you need to read a file with a while loop and ask the user for input in the same loop. Assign the file to an unused descriptor -- 3 in this case -- and obtain the user input from standard input:
exec 3< file.txt while read line <&3 do echo "$line" echo "what is your input? " read answer . . done exec 3<&- # close the file descriptor when done
Hey There,
Simply put, fork duplicates your shell (file descriptors, etc) in a subshell. Usually a forked process will then exec in that subshell.
exec exec's the command in your current shell, basically co-opting it.
In pure versions of exec, if you do, just at the shell prompt:
exec khs <-- instead of exec ksh
your shell will be replaced by khs, which doesn't exist, and you'll lose your shell (get logged out).
Redhat, OpenSolaris, and most Linux brands do a "fake exec" (really a fork and then exec) now, where, even when you call exec and flub it, you don't lose your shell.
Not a very technical explanation, but hopefully helpful
, Mike
Using the exec & eval Commands
One novice asked when it was suitable to exec and eval Unix commands:
exec mycommand eval mycommandThe exec command works differently depending on the shell; in the Bourne and Korn shells, the exec command replaces the current shell with the command being exec'ed. Consider this stub script:exec echo "Hello John" echo "Hello Ed" # end stubWhen the above stub executes, the current shell will be replaced when exec'ing the echo "Hello John" command. The echo "Hello Ed" command never gets the chance to execute. Obviously, this capability has limited uses.You might design a shell menu where the requirement is to execute an option that never returns to the menu. Another use would be restricting the user from obtaining the command line. The following last line in the user's .profile file logs the user out as soon as my_executable terminates:
exec my_executableHowever, most systems administrators probably use the exit command instead:my_executable exitDon't confuse exec'ing a Unix command with using exec to assign a file to a file descriptor. Remember that the default descriptors are standard input, output, and error or 0, 1, and 2, respectively.Let's consider an example where you need to read a file with a while loop and ask the user for input in the same loop. Assign the file to an unused descriptor -- 3 in this case -- and obtain the user input from standard input:
exec 3< file.txt while read line <&3 do echo "$line" echo "what is your input? " read answer . . done exec 3<&- # close the file descriptor when doneThe eval command is more interesting. A common eval use is to build a dynamic string containing valid Unix commands and then use eval to execute the string. Why do we need eval? Often, you can build a command that doesn't require eval:evalstr="myexecutable" $evalstr # execute the command stringHowever, chances are the above command won't work if "myexecutable" requires command-line arguments. That's where eval comes in.Our man page says that the arguments to the eval command are "read as input to the shell and the resulting commands executed". What does that mean? Think of it as the eval command forcing a second pass so the string's arguments become the arguments of the spawned child shell.
In a previous column, we built a dynamic sed command that skipped 3 header lines, printed 5 lines, and skipped 3 more lines until the end of the file:
evalstr="sed -n '4,\${p;n;p;n;p;n;p;n;p;n;n;n;}' data.file" eval $evalstr # execute the command stringThis command fails without eval. When the sed command executes in the child shell, eval forces the remainder of the string to become arguments to the child.Possibly the coolest eval use is building dynamic Unix shell variables. The following stub script dynamically creates shell variables user1 and user2 setting them equal to the strings John and Ed, respectively:
COUNT=1 eval user${COUNT}=John echo $user1 COUNT=2 eval user${COUNT}=Ed echo $user2 Pasting Files with pasteAnother novice asked how to line up three files line by line sending the output to another file. Given the following:file1: 1 2 3 file2: a b c file3: 7 8 9the output file should look like this:1a7 2b8 3c9The paste command is a ready-made solution:paste file1 file2 file3By default, the delimiter character between the columns is a tab key. The paste command provides a -d delimiter option. Everything after -d is treated as a list. For example, this paste rendition uses the pipe symbol and ampersand characters as a list:paste -d"|&" file1 file2 file3The command produces this output:1|a&7 2|b&8 3|c&9The pipe symbol character, |, is used between columns 1 and 2, while the ampersand, &, separates column 2 and 3. If the list is completely used, and if the paste command contains more files arguments, then paste starts at the beginning of the list.To satisfy our original requirement, paste provides a null character, \0, signifying no character. To prevent the shell from interpreting the character, it must also be quoted:
paste -d"\0" file1 file2 file3
The exec command will replace the parent process by whatever the command is typed.
Try the following:
exec ls -lAs you will have noticed, this closes the shell you are currently using. Why?
The exec command terminated the parent process and started (executed) the ls command and the ls command did what it was supposed to do and exited with a zero status, but ls has no parent process to return to, and thereby the shell is shut down.
If for example, we ran our eatout.sh script, but instead of running it as we have previously, we exec'd it, the script would run but would also close our terminal from which we ran the script.
exec eatout.shThis means that when the person finally types exit to exit the menu, they are sent back to the login prompt.
To see this in action, let's consider the following sequence of commands:
pstree -p |lessYou will notice that "pstree" starts with the init command or the init process. Somewhere further down this 'tree', init starts a shell (bash/ksh/csh) which is then going to run the pstree and the less command.
Now, in order to see exec at work, we need to find out the current process id.
Use:
echo $$to determine this (the ps command would give you the same information).
Now type the pstree command again, producing a diagram of your process tree.
pstree -p | lessSearch for your process id recorded from the echo above. Once you have located it, quit pstree and type:
exec bashThis would replace our current shell (our parent) with a new shell, and thus a new process id (PID).
echo $$You can also look at the pstree again.
By using the exec command, instead of making the new shell's parent your original shell, the new shell will be owned by init.
45.7 The exec CommandThe exec command will execute a command in place of the current shell; that is, it terminates the current shell and starts a new process (38.3) in its place.
Historically, exec was often used to execute the last command of a shell script. This would kill the shell slightly earlier; otherwise, the shell would wait until the last command was finished. This practice saved a process and some memory. (Aren't you glad you're using a modern system? This sort of conservation usually isn't necessary any longer unless your system limits the number of processes each user can have.)
exec can be used to replace one shell with another shell:
%exec kshwithout incurring the additional overhead of having an unused shell waiting for the new shell to finish.
exec also manipulates file descriptors (45.21, 45.22) in the Bourne shell. When you use exec to manage file descriptors, it does not replace the current process. For example, the following command makes the standard input of all commands come from the file formfile instead of the default place (usually, your terminal):
exec < formfile- ,
Copyright © 1996-2009 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
Disclaimer:
Last modified: August 08, 2009