Processes & Signals
Every running program on Linux is a process. Your shell is a process, every command you type starts one, and a server runs dozens of them all the time: the web server, the database, SSH, the logging service. When something is slow or stuck, the first job is to find the right process and decide what to do with it.
In this lesson you will list processes, read their details, watch them live, stop them with signals, and juggle several jobs in one terminal.
What a process is
When you run a program, the kernel creates a process for it and gives it a PID (process ID), a unique number. Each process also records its PPID (parent process ID), the process that started it, and the user it runs as, which decides what it is allowed to do. The very first process, PID 1, is systemd on Ubuntu; every other process descends from it.
echo $$
ps2481
PID TTY TIME CMD
2481 pts/0 00:00:00 bash
2617 pts/0 00:00:00 ps$$ is the PID of the current shell. Plain ps shows only processes in this terminal: your shell and ps itself, which ends as soon as it has printed.
ps: a snapshot of all processes
ps aux lists every process on the system. (The options come from old BSD style, so there is no dash.) Pipe it into grep or head:
ps aux | head -n 4
ps aux | grep [n]ginxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 22588 13312 ? Ss 08:01 0:02 /sbin/init root 2 0.0 0.0 0 0 ? S 08:01 0:00 [kthreadd] root 845 0.0 0.1 11280 2016 ? Ss 08:01 0:00 nginx: master process /usr/sbin/nginx www-data 846 0.0 0.1 12960 5124 ? S 08:01 0:00 nginx: worker process
| Column | Meaning |
|---|---|
USER, PID | Owner and process ID |
%CPU, %MEM | Share of processor and memory |
RSS | Real memory in use, in KB |
TTY | Terminal; ? means none (a background service) |
STAT | State: R running, S sleeping, D waiting for disk, T stopped, Z zombie |
COMMAND | The command line |
Names in square brackets such as [kthreadd] are kernel threads. The [n]ginx trick stops grep from matching its own command line. Even simpler is pgrep, which prints matching PIDs: pgrep -a nginx shows PIDs with their command lines. ps -ef is the other common style, and ps -eo pid,user,%mem,cmd --sort=-%mem | head shows the biggest memory users first.
top and htop: watch live
top refreshes the list every few seconds, with the busiest processes at the top:
toptop - 10:42:13 up 2:41, 1 user, load average: 0.08, 0.12, 0.10 Tasks: 118 total, 1 running, 117 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.3 us, 0.7 sy, 0.0 ni, 97.8 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 3911.2 total, 2180.4 free, 702.6 used, 1259.8 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 3208.6 avail Mem
The load average shows how many processes were running or waiting to run, averaged over 1, 5 and 15 minutes. As a rough guide, a load that stays above the number of CPU cores means the machine is overloaded. id is idle CPU, and wa is time spent waiting for the disk. Inside top, press M to sort by memory, P by CPU, k to kill a process and q to quit.
htop (sudo apt install htop) is a friendlier version with colours, bars for each CPU core, mouse support and a tree view (F5). Many people install it on every server.
Signals and kill
You control a process by sending it a signal, a small numbered message. Despite its name, kill simply sends signals:
| Signal | Number | Meaning |
|---|---|---|
SIGTERM | 15 | Please stop: the default. The program can clean up first |
SIGINT | 2 | Interrupt; what Ctrl+C sends |
SIGHUP | 1 | "Hang up"; many services reload their config on it |
SIGKILL | 9 | Stop immediately. Cannot be caught or ignored |
SIGSTOP / SIGCONT | 19 / 18 | Pause / resume |
kill 3120
kill -HUP 845
pkill -u kabir python3
kill -9 3120The first line asks process 3120 to finish politely. The second tells nginx's master process to reload its configuration. pkill sends a signal by name instead of PID (here only to Kabir's python3 processes), and killall does the same by exact program name. You can only signal your own processes unless you use sudo.
Jobs: foreground and background
A command normally runs in the foreground: the shell waits for it to finish. Put & at the end to run it in the background and get your prompt back at once. Bash calls these jobs and numbers them per terminal.
sleep 100 &
sleep 200 &
jobs
kill %1
jobs[1] 4012 [2] 4013 [1]- Running sleep 100 & [2]+ Running sleep 200 & [1]- Terminated sleep 100 [2]+ Running sleep 200 &
[1] 4012 means job 1 with PID 4012. %1 refers to job 1. Other job controls:
Ctrl+Zpauses the foreground job and returns the prompt.bgresumes a paused job in the background;fgbrings a job back to the foreground (fg %2).- Background jobs still die when you close the terminal or your SSH session drops.
nohup command &keeps one running after you log out, writing its output tonohup.out. For anything long-lived, a systemd service (see Services with systemd & systemctl) or a terminal multiplexer such astmuxis the better tool.
Advanced: priority with nice
Every process has a niceness from -20 (highest priority) to 19 (lowest). A "nice" process lets others go first. Start heavy jobs, such as large backups, with low priority so the website stays fast:
nice -n 15 tar -czf /backup/site.tar.gz /var/www/shop
sudo renice -n 5 -p 3120Normal users can only make their processes nicer (higher numbers); lowering the number needs sudo. The NI column in top shows the value.
Common mistakes
- Reaching for
kill -9first. Try plainkilland give the program time to clean up. - Killing the wrong PID. PIDs are reused. Check with
ps -p PID -o pid,user,cmdright before you kill. - Expecting
&jobs to survive logout. Usenohup,tmuxor a systemd service. - Confusing
Ctrl+ZwithCtrl+C.Ctrl+Zonly pauses; the process still holds memory and files until youfgor kill it.
Key points
- Every process has a PID, a parent (PPID) and an owner; PID 1 is systemd.
ps auxlists all processes;pgrep -a namefinds them;topandhtopshow them live.kill PIDsends SIGTERM (polite);kill -9sends SIGKILL (forced);kill -HUPoften reloads config.&starts a background job;jobs,fg,bgandCtrl+Zmanage jobs in the current terminal.niceandrenicelower or raise a process's priority.
Exercise
Start sleep 500 in the background and sleep 600 in the foreground. Pause the foreground one with Ctrl+Z and resume it in the background. List your jobs, then find the PID of the sleep 500 process with pgrep, stop it politely with kill, and bring the other job to the foreground and stop it with Ctrl+C.
Show solution
sleep 500 &
sleep 600
bg
jobs
pgrep -a sleep
kill 5120
fg[1] 5120 ^Z [2]+ Stopped sleep 600 [2]+ sleep 600 & [1]- Running sleep 500 & [2]+ Running sleep 600 & 5120 sleep 500 5121 sleep 600 [1]- Terminated sleep 500 sleep 600 ^C
Ctrl+Z shows ^Z and marks the job Stopped; bg restarts it in the background. pgrep -a gives the PIDs, and plain kill sends SIGTERM. fg brings job 2 back, and Ctrl+C sends SIGINT to end it.
Quick Quiz
1. What is PID 1 on Ubuntu?
systemd is started first by the kernel and is the ancestor of every other process.
2. Which signal does kill 1234 send by default?
Plain kill sends SIGTERM, which lets the program shut down cleanly.
3. What does Ctrl+Z do to a running foreground command?
Ctrl+Z stops (pauses) the job; fg or bg resumes it.
4. In top, a 2-core server shows load average: 6.10, 5.80, 5.95. What does that suggest?
A load that stays well above the number of cores means processes are queuing for the CPU.
Learn Linux with a mentor
Free lessons get you started. Our Ethical Hacking & Cyber Security training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
