From Executable to Process
One program, several different things
Section titled “One program, several different things”People use the word program to mean source code, an executable file, or a running process. When we investigate what a program does, we need to be clear about which one we mean. Reading a file on disk tells us something different from inspecting a process that has started running.
- Source code describes behavior in a language such as C.
- An executable file stores information and machine code in a format Linux knows how to load.
- A process is one running instance with an identity, memory, execution state, and operating-system resources.
An executable can sit on disk without being run. Starting it creates a process with its own lifetime and state. That process can be executing instructions, waiting for input, or sleeping, as the example below will show.
The executable contains code and information needed to load it. To see what happens during a particular run, we inspect the process: its memory, output, open files, and interactions with the operating system.
Inspect an executable before running it
Section titled “Inspect an executable before running it”We’ll use sleep, a utility that waits for a specified amount of time before exiting. That gives us time to inspect its process while it waits. First, find the executable your shell would select:
command -v sleepOn the course’s Ubuntu VM, this will normally print /usr/bin/sleep. command -v asks the shell which command it would run for that name, so we can use the path it reports instead of guessing where the executable is installed.
Store the result in a shell variable so later commands use the exact path you found:
sleep_path="$(command -v sleep)"printf '%s\n' "$sleep_path"Now inspect the file itself:
file "$sleep_path"stat "$sleep_path"file should identify an ELF executable or shared object for your machine’s architecture. stat reports its size, ownership, permissions, and timestamps. So far, we’ve inspected the executable without starting a sleep process.
Ask the shell to start it
Section titled “Ask the shell to start it”Run sleep for two minutes and place it in the background:
sleep 120 &The & starts the command in the background, so the shell returns your prompt while sleep is still running. The shell prints a job number and a process ID, usually shortened to PID.
The shell also stores the PID of the most recently started background process in $!. Save it immediately:
sleep_pid=$!printf 'PID: %s\n' "$sleep_pid"The variable is named sleep_pid; $sleep_pid asks the shell to substitute its stored value. Quoting "$sleep_pid" keeps that value as a single argument.
Inspect the process it created:
ps -p "$sleep_pid" -o pid,ppid,stat,comm,argsThe headings mean:
| Field | What it tells us |
|---|---|
PID |
The identity Linux assigned this process |
PPID |
The process ID of its parent, normally your shell here |
STAT |
A compact description of its current process state |
COMMAND or COMM |
The short command name |
COMMAND or ARGS |
The command and arguments used to start it |
Linux assigns PIDs when processes are created. Your numbers will differ from those in another run; use the ones you recorded in this shell.
What happened between the command and the process?
Section titled “What happened between the command and the process?”Starting a process involves several steps. We’ll examine them more closely throughout this module. For now, use this outline:
- The shell interpreted the command line and found the
sleepexecutable. - The shell asked the Linux kernel to create and start a process.
- Linux inspected the executable format.
- The loader mapped the required code and data into the new process’s virtual address space.
- Linux prepared the arguments and initial execution state.
- The processor began executing at the program’s designated entry point.
This outline gives us more specific questions to investigate. Which parts of the executable were mapped into memory? Where did execution begin? How did the argument 120 reach the program? The next lessons examine those steps.
For a dynamically linked program, the startup path also includes loading the libraries it needs:
The shell, kernel, and dynamic loader each handle part of this work. execve replaces the calling process’s loaded program. An interactive shell usually creates a child process first, then has that child load the executable so the shell can keep running. Static executables don’t need the dynamic-loader step shown here.
Connect the process back to the file
Section titled “Connect the process back to the file”Linux exposes information about running processes through /proc, and each process gets a directory named after its PID.
List the process directory:
ls -ld "/proc/$sleep_pid"Now inspect the exe entry:
ls -l "/proc/$sleep_pid/exe"readlink "/proc/$sleep_pid/exe"The exe entry is a symbolic link to the executable loaded for this process. readlink prints its target. This should identify the same file that command -v sleep found. The paths may look different if one uses a symbolic link, such as /bin pointing to /usr/bin.
This gives us an evidence chain:
command name → executable path → PID → /proc/PID/exe → executable pathThe proc_pid_exe manual describes this link and its limitations, including what it can show after an executable has been unlinked.
One executable, two processes
Section titled “One executable, two processes”Now start a second process from the same executable:
sleep 120 &second_pid=$!printf 'First PID: %s\nSecond PID: %s\n' "$sleep_pid" "$second_pid"Then inspect them both together:
ps -p "$sleep_pid,$second_pid" -o pid,ppid,stat,comm,argsBoth processes use the same executable and received the same argument, but each has a different PID. Each also has its own /proc directory and execution state.
Run readlink on both of them:
readlink "/proc/$sleep_pid/exe"readlink "/proc/$second_pid/exe"Both links should point to the same executable. Together with the different PIDs, this shows that one executable file can be used by two separate processes.
Clean up the experiment
Section titled “Clean up the experiment”The processes will exit on their own after two minutes. If they’re still running, stop them now so we can check what disappears:
kill "$sleep_pid" "$second_pid"wait "$sleep_pid" "$second_pid"kill sends a termination signal by default. wait waits for these background processes to finish and collects their exit status. A Terminated message is expected here because we asked the processes to stop.
Confirm that neither process remains:
ps -p "$sleep_pid,$second_pid" -o pid,stat,comm,argsOnce both processes have ended and the shell has collected their status, ps should show only the headings. Their /proc directories should be gone too.
Check your result
Section titled “Check your result”After cleanup, the two PIDs should be gone while the executable file remains. That file can start another process. If a PID still appears, verify its command before stopping it; do not assume a reused PID is your old process.
Common failures and recovery
Section titled “Common failures and recovery”- A saved PID has no
psrow: the process ended. Start a new controlledsleep, replace the variable, and verify it before you continue. readlinkreports a missing path: check the process still exists, and check the PID variable actually belongs to it.- Two terminals show different job state: go back to the shell that launched the background process, and use
psfor the system-visible identity. - You aren’t certain the cleanup worked: verify each PID and command individually, send
TERM, wait, and then prove both rows are gone.
What this lets us investigate
Section titled “What this lets us investigate”You now have evidence for the distinction we started with: the executable file remained in place while two processes started and stopped. Their PIDs identified separate runs, and their /proc links connected both runs to the same file.
Next, Reading an ELF File examines the information Linux uses to load that executable.
Check your understanding
Section titled “Check your understanding”Knowledge check
Question 1 of 2
Practice complete
You've checked the key ideas. Revisit any explanation you need, then continue when it makes sense.