← Back to list

Fork and Exec: How Does Your Program Actually Start?

We write a program, type a command, press Enter, and within a fraction of a second, the program starts running.

Prachi Maruti Patil · 2026-07-06 04:01 · 0 claps · 3.9 min read
#fork #exec #process #operating-systems #gate
Open on Medium ↗
Wiki topics: 📰 · Journalism & News 🥊 · Combat Sports 🏃 · Running & Endurance

Fork and Exec: How Does Your Program Actually Start?

We write a program, type a command, press Enter, and within a fraction of a second, the program starts running.

Simple, right?

But have you ever wondered what actually happens after you hit Enter?

How does your shell stop what it’s doing and magically start your program?

Let’s find out with a simple analogy.

Imagine You’re Making a Presentation

Suppose you have an old PowerPoint presentation.

Instead of creating a brand-new presentation every time, what do you usually do?

You simply duplicate the old one and then edit the copy.

Why?

Because all the formatting, themes, fonts, and layouts are already there. It saves a lot of time.

Believe it or not, your operating system follows a very similar approach.

Step 1: The Shell Creates a Copy of Itself

Let’s say you type:

./program

The command first reaches the shell.

Now, the shell has a decision to make.

Should it stop itself and become your program?

No.

Instead, it first creates a copy of itself using the **fork()** system call.

Fork System call

Fork System call

Now there are two processes:

  • Parent Process → The original shell.
  • Child Process → A newly created copy.

At first glance, both look almost identical.

In fact, modern operating systems don’t even copy all the memory immediately. They use a technique called Copy-on-Write (COW), where both processes initially share the same memory pages. A real copy is made only when one of them modifies the data.

So creating a child process is much faster than you might think.

But Why Doesn’t the Child Start From the Beginning?

Here’s something that confuses almost everyone the first time.

If the child is a copy of the parent, shouldn’t it start executing from the first line of the shell program?

The answer is no.

When fork() creates the child, it copies the current execution state of the parent process.

That means the child already knows:

  • where the parent was executing,
  • the values stored in registers,
  • the stack,
  • the program counter,
  • and other process information.

So instead of starting from the beginning, both parent and child continue from the instruction immediately after the fork() call.

The only difference is the return value:

  • In the parent, fork() returns the PID of the child.
  • In the child, fork() returns 0.

This tiny difference helps both processes decide what to do next.

So… Why Do We Need exec()?

At this point, something important has happened.

The child process is still running the shell program.

But that’s not what we want.

We want it to run our program.

This is where **exec()** comes into the picture.

When the child calls exec(), the operating system replaces the entire program inside that process with the new program you requested.

Exec System Call

Exec System Call

Think back to our PowerPoint analogy.

You duplicated the presentation.

Now imagine deleting every slide in the duplicate and replacing them with an entirely different presentation.

The duplicated file still exists, but its content is completely different.

That’s exactly what exec() does.

The process itself stays the same (it even keeps the same Process ID), but everything inside it — its code, data, stack, and memory — is replaced by the new program.

The old shell code disappears.

Your program starts running.

What If We Never Call exec()?

Now here’s an interesting question.

What happens if we call fork() but never call exec()?

The answer is simple.

Nothing gets replaced.

The child continues running the same shell program as the parent.

Instead of running your requested program, you’ll simply have two shell processes.

It’s just like duplicating a PowerPoint and forgetting to edit the copy.

Now you have two identical presentations.

What If We Call exec() Before fork()?

Another interesting thought.

Why don’t we simply call exec() first?

The reason is that exec() doesn't create a new process.

It replaces the currently running process.

So if the shell directly called exec(), the shell itself would disappear and become your program.

Your command would run successfully.

But after it finished…

There would be no shell left to accept your next command.

Imagine opening PowerPoint, replacing the application itself with your presentation, and then wondering why PowerPoint no longer exists after closing the file.

That would be a disaster for a command-line interface.

That’s why shells always follow this sequence:

  1. Create a child using fork().
  2. Let only the child call exec().
  3. Keep the parent shell alive so it can accept the next command after your program finishes.

The Complete Flow

Process Loading Complete flow

Process Loading Complete flow

Quick Recap

Whenever you run a command:

  1. The shell receives your command.
  2. It creates a child process using fork().
  3. Both parent and child continue from the instruction after fork().
  4. The child calls exec().
  5. exec() replaces the child with your program.
  6. The parent shell stays alive and waits (or continues), ready to accept your next command.

Final Takeaway

Think of it this way:

  • **fork()* says, "Let me make a copy of myself."*
  • **exec()* says, "Now replace that copy with the program the user actually wants to run."*

Together, these two system calls are the reason you can run one command after another without your shell disappearing.

The next time you type a command in the terminal, remember that your shell isn’t transforming into your program — it quietly creates a child, lets the child become the program, and patiently waits for you to type the next command.


메타데이터
post_id
2f41a2881eb7
slug
fork-and-exec-how-does-your-program-actually-start-2f41a2881eb7
url
https://medium.com/@prachimarutipatil19/fork-and-exec-how-does-your-program-actually-start-2f41a2881eb7
canonical_url
https://medium.com/@prachimarutipatil19/fork-and-exec-how-does-your-program-actually-start-2f41a2881eb7
author_url
https://medium.com/@prachimarutipatil19
status
ok
fetched_at
2026-09-13 18:12:38