Processes, signals & jobs
ps, pgrep, top, signals and kill, nice, and foreground/background job control.
Every running program on Linux is a process. Your shell is a process, every command you type starts new ones, and a server runs hundreds in the background. In this lesson you'll learn to list and inspect processes, stop them with signals, juggle jobs in your terminal and control their priority.
What is a process?#
A process is a running instance of a program. Each one has:
- a PID (process ID), a unique number;
- a PPID, the PID of the parent that started it (processes form a tree rooted at PID 1, which is
systemdon most distros); - an owner (user), which decides what it may access;
- a state, memory, open files, environment variables and a current directory.
$$ is the shell's own PID. With no options, ps lists the processes in your current terminal.
Listing processes: ps#
The two classic forms are worth memorising:
Key columns in ps aux:
pstree -p (package psmisc) draws the tree nicely.
Finding processes by name: pgrep and pidof#
ps aux | grep name works, but it also matches the grep itself. pgrep is cleaner:
pidof nginx returns the PIDs of a program by exact name, and pgrep -u www-data finds processes owned by a user.
Signals and kill#
Processes are controlled with signals, small messages from the kernel or another process. The important ones:
kill PID: by PID (alsokill -TERM PID,kill -15 PID)pkill pattern: by name or pattern (-ffor the full command line,-u userfor an owner)killall name: by exact name (psmisc)
💡 Escalate gently. Send
SIGTERMfirst and wait a few seconds; well-behaved programs save state and clean up temp files and locks. Usekill -9only when a process ignores TERM. SIGKILL gives it no chance to clean up.
A process in state D (uninterruptible I/O, often a hung NFS mount or failing disk) can't even be killed with -9 until the I/O returns. A Z zombie has already exited and is waiting for its parent to collect its exit status; it uses no resources except a PID, and goes away when the parent does.
Foreground, background and jobs#
By default a command runs in the foreground: it owns your terminal until it finishes. Bash's job control lets you juggle several commands:
(Terminated appears because job 1 was killed. Run kill %2 or fg to deal with the other one. jobs -l also shows PIDs.)
Interactively you'll also use:
A typical moment: you start tar on a huge directory, realise it will take ages, press Ctrl+Z, type bg, and carry on working.
Surviving logout: nohup, disown and tmux#
When you close a terminal, the shell sends SIGHUP to its jobs and they usually die. Options:
For interactive work on servers, use a terminal multiplexer: run tmux (or screen), start your work, detach with Ctrl+B then D, log out, and later tmux attach to pick up exactly where you were. For anything that should run permanently, write a systemd service (coming up soon).
Priorities: nice and renice#
The CPU scheduler favours processes with a lower niceness. It ranges from -20 (highest priority) to 19 (lowest), and the default is 0.
$! is the PID of the last background command. Regular users can only make processes nicer (raise the number); lowering it needs sudo. For disk-heavy jobs, ionice -c3 cmd gives the job idle I/O priority. A good combination for backups is nice -n 19 ionice -c3 tar ....
Live views: top and htop#
top refreshes every few seconds. Useful keys: P sort by CPU, M by memory, k kill a PID, 1 show each CPU core, q quit. The header shows uptime, load average, task counts and memory (all covered in depth in the performance lesson).
htop (sudo apt install htop / sudo dnf install htop) is friendlier: colours, mouse support, a tree view (F5), search (F3), and kill (F9).
Inspecting a process: /proc and lsof#
Each process has a directory under /proc/<PID>:
lsof -p PID lists a process's open files, and lsof -i :8080 shows which process is using a port (or ss -ltnp, covered in networking).
Common mistakes#
- Reaching for
kill -9first. It can corrupt data or leave lock files behind. Try plainkillfirst. ps aux | grep foomatching itself. Usepgrep -a foo.- Closing the SSH session on a long job. Use
tmux,nohup, or a systemd service. - Killing the wrong PID after the process restarted with a new one. Look it up again right before you kill.
- Thinking zombies need killing. They're already dead. Fix or restart the parent if they pile up.
What's next#
Long-running background programs are services. Next you'll manage them properly with systemd and journalctl.
Check your understanding
Quick quiz
1.Which signal does plain
kill <PID>send by default?2.You pressed Ctrl+Z on a long-running command. How do you let it keep running in the background?
3.What does
nice -n 10 ./backup.shdo?
Finished reading?
Mark this lesson complete to track your progress.