Linux exec Command: Process Control & FD Mastery
The exec command is a powerful built-in utility in Linux shells (such as Bash) that serves two primary purposes:
- Replace the current shell process
- Manipulate file descriptors without spawning new processes
Understanding exec is essential for writing efficient scripts, managing I/O streams, and building reliable containerized applications.
π Core Concept: Process Replacement #
In typical shell execution, running a command creates a child process. The shell waits for it to complete, then resumes control.
With exec, this behavior changes fundamentally:
- The current shell process is replaced entirely
- The PID remains the same
- The original shell no longer exists after execution
Example #
# The shell is replaced by 'ls'; session ends after execution
exec ls -l
Once ls completes, there is no shell to return toβso the session exits.
π File Descriptor Management #
One of the most powerful uses of exec is controlling file descriptors (FDs) at the shell level.
| FD | Name | Default |
|---|---|---|
| 0 | stdin | Keyboard |
| 1 | stdout | Terminal |
| 2 | stderr | Terminal |
Common Patterns #
Redirect all output #
exec > output.txt
All subsequent commands write to output.txt.
Redirect input #
exec < input.txt
All read operations pull from the file.
Create custom file descriptor #
exec 3> log.txt
echo "Log message" >&3
Close a descriptor #
exec 3>&-
Releases FD 3.
π οΈ Advanced Use Cases #
A. Centralized Logging in Scripts #
Instead of redirecting each command individually:
exec > >(tee -a script.log) 2>&1
echo "This will be logged automatically."
- Captures both stdout and stderr
- Streams output to terminal and log file simultaneously
B. Language Handoff (Process Morphing) #
A script can switch execution context mid-run:
#!/bin/bash
echo "Starting in Bash..."
exec python3 -c "print('Now running in Python context!')"
echo "This will NEVER execute"
After exec, the Bash process is replaced by Python.
C. TCP Communication via Bash #
Bash supports raw socket access using /dev/tcp:
exec 3<> /dev/tcp/google.com/80
echo -e "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n" >&3
cat <&3
- Opens a bidirectional TCP connection on FD 3
- Sends HTTP request and reads response
π³ exec in Docker: Why It Matters #
In container environments, exec plays a critical role in signal handling.
Without exec #
#!/bin/bash
my_app
- Shell remains PID 1
- Signals like
SIGTERMmay not propagate correctly
With exec #
#!/bin/bash
exec my_app
my_appbecomes PID 1- Receives signals directly
- Enables graceful shutdown
β Summary Checklist #
-
Efficiency No additional processes are created
-
Persistence File descriptor changes affect the entire session
-
Finality Code after
exec <command>will not execute
π§ Key Takeaway #
The exec command is less about running programsβand more about redefining the current process environment.
It enables:
- Precise control over execution flow
- Persistent I/O redirection
- Clean integration with container runtimes
Mastering exec is a step toward writing production-grade shell scripts and infrastructure tooling.