Linux › Module 6 › Lesson 1
Processes (ps, top, kill)
List and manage processes with ps, top, and kill
Opening
What is actually running?
A Linux box is a crowd of programs, each with a process ID (PID). Malware, cryptominers, stuck test scripts, and leftover SSH sessions hide in that crowd — and so do backups, databases, and your own shell. Legitimate admins use ps and top every day. kill asks a process to stop; kill -9 forces it. You cannot secure a machine if you cannot see what it is doing — and you should not pull the SIGKILL fire alarm as your first move. This lesson teaches observation first, polite signals second, and force last — only on processes you started yourself on a VM or WSL you administer. Never practice by killing a coworker's job or PID 1 "to see what happens."
1. PID: the handle for a running program
When the kernel starts a program, it assigns a PID — a number unique on that system until reuse. ps and top show PIDs. kill needs a PID (or a name via killall / pkill — which are easy to overuse). Write the PID down before you signal anything. If you kill the wrong number, you may stop a backup, a database checkpoint, or your own shell session.
Your shell has a PID too: echo $$ prints it. Background jobs remember $! as the last background PID. Those two expansions are how you practice signals safely: start sleep yourself, note $!, signal that number only. Do not invent PIDs from a scary-looking top row without reading the COMMAND column.
2. ps aux: a snapshot, not a movie
ps aux lists many processes with user, PID, CPU%, memory, and the command line. ps -ef is the System V-style sibling with different columns. Pipe to grep on a string you expect: ps aux | grep ssh. Remember grep will also match its own command line — that is normal, not proof of a second sshd. Use ps aux | grep '[s]sh' as a trick, or just ignore the grep line consciously.
Read the USER, STAT, and COMMAND columns before you decide anything is "suspicious." A process you do not recognize, running as root, with a path in /tmp, is worth investigating on a system you administer — not "kill -9 first, ask later." Snapshot, note parent PID if shown (ps -ef or pstree if available), then decide. On a shared host, escalate to the owner; do not freestyle signals.
ps is a photograph. Processes start and exit between photographs. If you need a live view of CPU and memory churn, that is top (or htop). Use ps when you want a searchable, pipeable list for notes or scripts you own.
3. top and htop: live CPU and memory
top refreshes a live view of load, memory, and the busiest processes. Press q to quit. htop is a friendlier curses interface if installed via your package manager on a machine you administer. Unexplained 100% CPU is a classic cryptominer or runaway loop symptom — still not automatic proof of malware. Compilers, video encodes, and backups also peg a core.
Identify the PID and full command. On your own VM, you might stop a stuck test script you launched. On production, you follow incident process, keep evidence (command line, user, parent), and avoid destroying the only sample of a malicious binary by panicking. Observation beats the hammer.
4. kill vs kill -9: polite stop, then last resort
kill PID sends SIGTERM (signal 15) by default: "please shut down." Well-written programs flush files, close sockets, release locks, and exit. kill -15 PID is the same idea made explicit. kill -9 PID sends SIGKILL: the kernel tears the process down immediately. No cleanup. Databases can be left mid-write. File copies can be truncated. Prefer SIGTERM, wait, check with ps -p PID, then consider -9 only if it is stuck and you accept the mess.
Malware that respawns from a parent, cron job, or systemd unit will come back after -9 anyway — so you needed the persistence mechanism, not a bigger hammer. Order of operations on a process you started yourself: Ctrl+C in the foreground, or kill PID, wait, then kill -9 only as last resort. Do not kill -9 sshd, systemd, or PID 1 because top looked scary.
5. Zombies and orphans (concepts, not spells)
A zombie is a child that has exited but whose parent has not yet read the exit status (wait). It holds a PID slot, not a secret backdoor. You cannot "kill -9 the zombie" in the usual sense; the parent (or a reboot in extreme stuck cases) has to reap it. An orphan is a child whose parent died; init or systemd adopts it. Neither word means "malware." They are process-lifecycle vocabulary so you do not panic at a Z state in ps.
6. Wrong vs right: SIGKILL as the first reflex
Worked failure mode — kill -9 on the first high-CPU line:
Wrong
top shows 90% CPU. You kill -9 the PID without reading the command. It was a compile, a backup, or a database checkpoint. Data is inconsistent. The miner you imagined was not even there. You also lost the chance to capture the command line and parent for notes. On a shared box, you may have killed someone else's legitimate work.
Right
ps aux | grep the name, copy PID + full command + user. On a process you own, try SIGTERM (kill PID). Use kill -9 last. If it respawns, look at the parent and how it was started — not a louder signal. Keep practice kills limited to sleep jobs you started in $HOME/cyberlium-lab sessions.
7. Practical: list processes on your machine
Run these as yourself on YOUR VM or WSL. Do not kill system PIDs. If you start a sleep in another terminal or background job, you may SIGTERM that sleep only. Document PID and command before any signal.
ps / top / kill — observe first (your machine)
# Snapshot of YOUR session's world — VM/WSL you own ps aux | head -n 15 echo "My shell PID: $$" ps -p "$$" -o pid,user,cmd # Search carefully (expect to see the grep line too) ps aux | grep ssh | head # Live view — press q to quit (do not kill random rows) # top # htop # if installed on your box # Optional: start a harmless process YOU own, then stop it politely mkdir -p "$HOME/cyberlium-lab/processes" cd "$HOME/cyberlium-lab/processes" sleep 120 & sleep_pid=$! echo "sleep PID is $sleep_pid" ps -p "$sleep_pid" -o pid,stat,cmd kill "$sleep_pid" # wait a moment; confirm it exited sleep 1 ps -p "$sleep_pid" || echo "sleep exited after SIGTERM" # Last resort only on a process you started that ignores SIGTERM: # kill -9 "$sleep_pid" # DO NOT: kill -9 1 # DO NOT: killall sshd on a machine you did not intend to disrupt # DO NOT: signal another user's PIDs "for practice"
Mission: snapshot before you signal
Run ps aux | head and note two PIDs you recognize (your shell, a browser, etc.). Optional: start sleep 60 in the background, kill it with SIGTERM (not -9), confirm it exited. Write one sentence: "I use kill -9 last because ___." Do not signal PIDs you do not own.
Stuck? Ask Cyberlium AI Mentor
If PID vs kill -9 is fuzzy, ask Cyberlium AI Mentor for a hint — not a recipe to kill another user's jobs. Try: "Hint only: default kill signal vs -9 — which lets a program clean up?" Or: "Hint only: what is a zombie process in one sentence?" Stay on processes you started yourself.
You can read PIDs, snapshot with ps, watch load with top, distinguish zombies from malware vocabulary, and treat kill -9 as a last resort on your own stuck jobs. Next — Installing Tools (apt & packages) — how software actually lands on Debian/Ubuntu/Kali and why random PPAs are risky.
Knowledge Check
APPLY: A teammate's backup job is at 80% CPU in top. They ask you to "just kill -9 it." Best first response?
Multiple choice
Knowledge Check
APPLY: Why might malware come back after kill -9 on one PID?
Multiple choice
Knowledge Check
APPLY: True or False: A zombie process is a child that exited before the parent collected its status — not automatically malware.
True or False