Which processes are running: ps and pgrep
Count the copies of one process and save the number.
A service is acting up, and the first question is usually how many copies
of it are running right now, and whether it's running at all. Maybe a
worker crashed. Maybe a bad deploy left two of them. ps, pgrep and
pidof give the answer, and kill stops the extra copy.
Where to practice
The examples below work in an ubuntu:24.04 container. You can bring up
the same one yourself:
docker run --rm -it ubuntu:24.04 bash
Inside it, start three background processes to experiment on:
sleep 600 & sleep 600 & sleep 600 &
sleep 600 waits 600 seconds and does nothing. The & sends the command
to the background, so the terminal is free for the next one right away.
On macOS, ps and pgrep are different (from BSD); the difference is
described in "Common mistakes".
Process and PID
A process is a running program. One program can run as several copies, and each copy is a separate process. A process has a PID (process ID) number: it's used to find the process and send it signals. Each process also has a parent, whose number is called the PPID.
What ps shows
ps without flags shows only the current terminal's processes:
ps
PID TTY TIME CMD
1 pts/0 00:00:00 bash
9 pts/0 00:00:00 sleep
10 pts/0 00:00:00 sleep
11 pts/0 00:00:00 sleep
12 pts/0 00:00:00 ps
Our three sleep processes show up here because we started them from
this same terminal. A server's services aren't started by your terminal,
so they won't be in this list.
Every process in the system
To see everything running in the system, you need the -e flag (every),
and -f (full) adds the UID, PPID and full command line columns:
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 5 18:36 pts/0 00:00:00 bash
root 9 1 0 18:36 pts/0 00:00:00 sleep 600
root 10 1 0 18:36 pts/0 00:00:00 sleep 600
root 11 1 0 18:36 pts/0 00:00:00 sleep 600
root 13 1 0 18:36 pts/0 00:00:00 ps -ef
The CMD column shows the command along with its arguments. There's also
ps aux from the BSD tradition: same processes, different columns
(%CPU, %MEM, STAT). If a line gets cut off by the terminal width,
add ww: ps -efww.
Searching by name with grep
On a live server, ps -ef prints hundreds of lines, and they get filtered
with grep:
ps -ef | grep sleep
root 9 1 0 18:36 pts/0 00:00:00 sleep 600
root 10 1 0 18:36 pts/0 00:00:00 sleep 600
root 11 1 0 18:36 pts/0 00:00:00 sleep 600
root 15 1 0 18:36 pts/0 00:00:00 grep sleep
The fourth line is extra: grep sleep is itself running at the moment of
the snapshot, and its own command line has the word sleep in it. If you
count the lines with wc -l, you get 4 instead of 3.
Square brackets work around this:
ps -ef | grep '[s]leep' | wc -l
3
To grep, the pattern [s]leep means "the letter s, then leep", which
matches sleep. But grep's own command line has [s]leep written with
the brackets, and that doesn't match the pattern. The quotes keep the
shell from treating the brackets as a filename pattern.
There's a second trap with grep on ps -ef. It searches the whole line,
arguments included. A process like tail -f /tmp/sleep.txt will also
match, even though it isn't sleep.
pgrep: searching without grep
pgrep searches processes by name and prints their PIDs. It doesn't
include itself in the result:
pgrep sleep
9
10
11
Useful flags:
pgrep -c sleepprints the count:3.pgrep -l sleepadds the name:9 sleep.pgrep -a sleepadds the full command line:9 sleep 600.pgrep -x sleeplooks for an exact name match. Without-xthe pattern is matched inside the name, sopgrep sleealso findssleep.pgrep -f patternsearches the whole command line, not just the name.
The difference between name and command line matters. A process's name is
the program's name (up to 15 characters), say sleep or tail. The
command line includes the arguments. Let's start tail on a file whose
name contains sleep:
tail -f /tmp/sleep.txt >/dev/null &
pgrep -c sleep
3
pgrep -cf sleep
4
With -f, tail gets counted too, because the word is in its arguments.
Without -f, its name tail doesn't match sleep.
If a program is a script starting with #!/bin/bash, the process name
comes from the script file's name. In ps -ef such a process looks like
/bin/bash /usr/local/bin/script-name, and pgrep script-name finds it.
pidof
pidof prints the PIDs of every process of a program on one line:
pidof sleep
11 10 9
You can count them with wc -w (words): pidof sleep | wc -w gives 3.
pidof doesn't find scripts by default; that needs the -x flag. Another
option on Linux: ps -C sleep shows processes with that name in regular
ps format.
How to stop a process
kill PID sends the process a SIGTERM signal (number 15): "wrap up".
A well-behaved program closes its files and exits on it.
kill 9
pgrep -c sleep
2
If a process doesn't respond to SIGTERM, there's kill -9 PID (SIGKILL).
It can't be caught; the kernel kills the process immediately, and the
program has no chance to clean up after itself. So -9 is a last resort,
not the first step.
pkill works like pgrep, except instead of printing it sends a signal
to every process it finds. It's easy to hit the wrong thing with it:
pkill -f word stops everything with that word anywhere in its command
line. Check who the pattern matched with pgrep -a first, and only then
stop it.
Common mistakes
pswithout flags on a server: you only see your own terminal's processes, no services there. For the whole system you needps -eforps aux.ps -ef | grep name | wc -lcountsgrepitself too. Use the[n]ametrick orpgrep -c.grepandpgrep -fsearch the whole command line, so other processes with that word in their arguments get counted too (tail -f name.log,vim name.conf). Check the full lines withpgrep -abefore counting or stopping anything.pkill -f wordwithout checking first: stops everything that matched.kill -9as the first move: the program doesn't get a chance to exit cleanly.- macOS: BSD
pgrepdoesn't know-c, and-athere means something else and doesn't print the command line. You can count withpgrep sleep | wc -l;pgrep -lfshows the command line. There's nopidofon macOS, andps -Cdoesn't work either, butps -efdoes.
What you'll need for the tasks
- See every process in the system with
ps -ef. - Count the processes of one program with
pgrep -corgrepusing the[n]ametrick, without counting extra lines. - Tell a process name apart from its command line (
pgrepandpgrep -f,pgrep -a). - Stop one specific process by PID with
kill. - Save a number to a file with
>, as in previous lessons.
Practice in your browser
Linux runs right here. Solve the task and we'll save your progress automatically.
How many tail processes
We started several tail processes in the background. Count how many instances are running right now and save the number to /tmp/answer.
0%
Go through it with an AI agent
The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.
Tell the agent: use MCP izi, give me lesson terminal-basics-03-running-processes
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress