Back to Blog
LinuxJuly 1, 20264 min read

Linux Process Management: Using lsof and fuser for Zombie Processes

Master Linux process management with the lsof command and fuser command. Learn how to identify and kill hung processes before they impact your server.

linuxsysadminbashtroubleshootingprocessesCLI

Last week, I spent three hours debugging a production server that refused to unmount a network-attached storage drive. The system kept throwing "device busy" errors, and my usual ps aux checks showed absolutely nothing suspicious. It’s a classic headache in Linux process management where a hidden file descriptor keeps a resource locked long after the parent application thinks it's finished.

When you're dealing with stubborn, hung, or zombie processes, relying on standard process lists isn't enough. You need to peek at the kernel's open file table.

The lsof command: Seeing what’s holding the lock

The lsof command—short for "List Open Files"—is my go-to utility for this. In Linux, everything is a file, which means if a process is hanging onto a socket, a pipe, or a directory, lsof will find it.

To find out what is locking a specific directory or file, run:

Bash
sudo lsof +D /mnt/data_storage

The +D flag tells lsof to search recursively through the directory. If you just want to check a specific file, drop the plus sign. What you’ll usually see is a list of PIDs (Process IDs) that have that file open. If you’ve already checked your memory management and confirmed it’s not a memory leak, a runaway file handle is almost always the culprit.

The fuser command: Quick identification and termination

While lsof gives you a detailed report, the fuser command is designed for action. It’s significantly faster if your only goal is to identify which process is blocking a resource and terminate it immediately.

If I need to see which process is using a specific port—say, port 8080—I use:

Bash
sudo fuser -v 8080/tcp

The -v (verbose) flag shows you the user, the PID, and the command access type. If you want to kill the process that is holding up that port, you can add the -k flag:

Bash
sudo fuser -k 8080/tcp

When to use which tool

ToolBest Use CaseOutput Style
lsofDeep inspection of file handlesVerbose, tabular
fuserRapid PID identificationCompact, actionable
killSending signals to PIDsManual, requires PID

Handling true zombie processes

A common misconception is that you can "kill" a zombie process. By definition, a zombie process is already dead—it's a process that has completed execution but still has an entry in the process table because its parent hasn't read its exit status.

Running kill -9 on a zombie won't do anything because the process doesn't exist in a state that can receive signals. You have to target the parent process. Use ps -o ppid= -p <zombie_pid> to find the parent, then restart that parent service. If you are running background workers with systemd, a simple systemctl restart <service> usually cleans up the orphan processes effectively.

My workflow for hung processes

I usually follow this sequence when a system resource feels "stuck":

  1. Identify: Use fuser to see if a process is actively using the resource.
  2. Inspect: Use lsof if fuser returns a PID I don't recognize, to see what other files that process has open.
  3. Signal: If it's a legitimate hung process (not a zombie), I send a SIGTERM (15) first.
  4. Force: Only if SIGTERM fails after about 5 seconds, I resort to SIGKILL (9).

I've learned the hard way to avoid kill -9 as a first resort. Killing a process abruptly can leave lock files on disk or corrupt database states, leading to much bigger problems than a simple hung process. If you're managing complex environments, always ensure your log management is set up so you can trace what the process was doing right before it hung.

What I’m still experimenting with is using bpftrace for even deeper observability into why these processes hang in the first place. Sometimes it's not a logic error, but a kernel-level I/O block that no standard user-space tool can fully diagnose.

FAQ

Can I kill all processes using a specific file? Yes, use fuser -k /path/to/file. Be careful, as this will terminate every process accessing that file, which might include system-critical services.

What is the difference between SIGTERM and SIGKILL? SIGTERM (15) tells a process to shut down gracefully, allowing it to save state or close handles. SIGKILL (9) forces the kernel to terminate the process immediately, giving it no chance to clean up.

Why does my process show up as 'Z' in top? That 'Z' stands for Zombie. It’s waiting for its parent to acknowledge its exit. You cannot kill it; you must address the parent process instead.

Similar Posts