Linux Use of exec
Links: 104 Linux Index
Basics¶
Whenever we run any command in a Bash shell, a subshell is created by default, and a new child process is spawned (forked) to execute the command.
-
When using
exec, however, the command followingexecreplaces the current shell.- This means no subshell is created and the current process is replaced with this new command.
-
Example:
$ pstree -p
init(1)─┬─init(52)───bash(53)
├─init(78)───bash(79)───pstree(108)
└─{init}(7)
$ echo $$
79
$ exec sleep 300
- We checked the PID of the current shell using echo
$$(gives the PID of the current process) andpstreecommands and then executed a sleep of 300 seconds usingexec. - Let’s now switch to a different terminal to check the process list
$ ps -aef | grep $USER
user1 53 52 0 23:37 tty2 00:00:00 -bash
user1 79 78 0 23:39 tty1 00:00:00 sleep 300
user1 111 53 0 23:40 tty2 00:00:00 ps -aef
user1 112 53 0 23:40 tty2 00:00:00 grep --color=auto
sleep command.
- We’ll also observe that after 300 second sleep finishes, the session (terminal), which had PID 79, exited since the shell was replaced by exec command, and its execution has completed.
What is exec¶
execis a command with two very distinct behaviours, depending on whether at least one argument is used with it, or no argument is used at all.- If at least one argument is passed, the first one is taken as a command name and
exectry to execute it as a command passing the remaining arguments, if any, to that command. - If the command exists and is executable, it replaces the current shell.
- That means that if
execappears in a script, the instructions following theexeccall will never be executed. - This is why we always see
execat the end of the scripts. - A successful
execnever returns.
- That means that if
- If no argument is passed,
execis only used to redefine the current shell file descriptors.- The shell continue after the
exec, unlike with the previous case, but the standard input, output, error or whatever file descriptor has been redirected take effect.
- The shell continue after the
Use of exec¶
- Let’s assume Bash is not the default shell of our Linux box. Interestingly, using
execcommand, we can replace the default shell in memory with the Bash shell by adding it to the user’s login profile:exec bash
- We can reset all the environment variables for a clean run using the
-coptionexec -c printenvprintenvcommand lists the environment variables, giving it as an argument toexeccommand here prints an empty output.
- Used in conjunction with the
findcommand. execis also often used as an optimisation.- If a shell script is going to run some other program as the last thing it does, running the other program without
execmeans the shell has to sit there waiting for the other process to finish, doing nothing useful. - Using
execmeans the shell hands directly off to the other program, and there's no extra useless process hanging out taking up resources.
- If a shell script is going to run some other program as the last thing it does, running the other program without
Usage within bash scripts¶
- We can call scripts or other programs within a script using
execto override the existing process in memory. - This implementation is particularly useful in cases when we don’t want to return to the main script once the sub-script or program is executed
#! /bin/bash
while true
do
echo "1. Disk Stats "
echo "2. Send Evening Report "
read Input
case "$Input" in
1) exec df -kh ;;
2) exec /home/SendReport.sh ;;
esac
done
- If we didn't use
execwe would have never exit from the while loop:
Redirection¶
- If you run
exec > fileinstead, then the redirection applies to the entire shell: Any output produced by the shell is written tofileinstead of to your terminal. For example here
bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST
- I exit my shell (so that the redirection no longer applies) and I see that
fileindeed contains the output of thedatecommand I ran earlier. - This can be used for logging in scripts
#! /bin/bash
script_log="/home/shubh/log_`date +%F`.log"
exec 1>>$script_log
exec 2>&1
datee
echo "Above command is wrong, error will be logged in log file"
date
echo "Output of correct date command will also be logged in log file, including these echo statements"
Using $@ with exec¶
-
It takes all the variables passed to the script and then passes it to the command.
-
Output:
Use of $@ in docker entrypoint.sh¶
- Sample
entrypoint.shscript
- It basically takes any command line arguments passed to
entrypoint.shusingCMDinstruction inDockerfileor while running the container and execs them as a command.- The intention is basically "Do everything in this
.shscript, then in the same shell run the command the user passes in on the command line or what is defined in theDockerfile". - If you have an image with an entrypoint pointing to
entrypoint.sh, and you run your container asdocker run my_image server start, that will translate to runningentrypoint.sh server startin the container.- At the exec line
entrypoint.sh, the shell running as pid 1 will replace itself with the commandserver start
- At the exec line
- The intention is basically "Do everything in this
exec "$@" is critical for signal handling.
- Without using
exec, theserver startin the above example would run as another pid, and after it exits, you would return to your shell script. - With a shell in pid 1, a SIGTERM will be ignored by default. The reason being processes running as PID1 usually behave different than when running not as PID1. Many processes ignore
SIGTERMwhen running as PID1. - That means the graceful stop signal (
SIGTERM) thatdocker stopsends to your container, would never be received by theserverprocess since it will be sent to shell first (PID1) and it will ignore it. - After 10 seconds (by default),
docker stopwould give up on the graceful shutdown and send a SIGKILL that will force your app to exit, but with potential data loss or closed network connections, that app developers could have coded around if they received the signal. - It also means your container will always take the 10 seconds to stop.
- More about Signals
Summary¶
- Without
exec, the parent shell process survives and waits for the child to exit. - With
exec, the child process replaces the parent process entirely so when there's nothing for the parent to do after forking the child, I would considerexecslightly more precise/correct/efficient. -
without exec
- parent shell starts
- parent shell forks child
- child runs
- child exits
- parent shell exits
-
with exec
- parent shell starts
- parent shell forks child, replaces itself with child
- child program runs taking over the shell's process
- child exits
References¶
- The Uses of the Exec Command in Shell Script | Baeldung on Linux
- https://stackoverflow.com/a/48096779
Last updated: 2023-01-22