↓ Skip to main content

Linux exec Command: Process Control & FD Mastery

·466 words·3 mins

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 SIGTERM may not propagate correctly

With exec
#

#!/bin/bash
exec my_app
  • my_app becomes 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.

Related