The lsof Command Explained for Mac Users

Master the lsof command to find out which processes have files open on your Mac. A guide for developers and power users.

Your external drive won’t eject. macOS gives you the maddeningly vague message that “one or more programs may be using it.” Which programs? It won’t say. This is where lsof comes in.

The name stands for “list open files,” and it does exactly that. On Unix-based systems like macOS, almost everything is treated as a file, including network connections, devices, and disk volumes. When you can’t eject a drive, lsof tells you precisely which process is holding it hostage.

Basic syntax

The simplest way to use lsof for ejection problems is:

lsof /Volumes/YourDriveName

Replace “YourDriveName” with the actual name of your drive. If the name has spaces, wrap the whole path in quotes:

lsof "/Volumes/My Backup Drive"

This returns matching open handles that lsof can inspect on that volume. Permissions and timing can limit the result. Each line shows the process name, its ID (PID), the user running it, and information about the specific file being accessed.

Reading the output

A typical lsof output looks something like this:

COMMAND     PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
TextEdit   6789   you    4u   REG   1,12      128  ...  /Volumes/External/notes.txt
Finder     5678   you    3r   DIR   1,12     1024  ...  /Volumes/External

The columns that matter most are COMMAND (the process name), PID (process ID you’d use to kill it), and NAME (the actual file path being accessed).

The FD column shows the access mode of that handle. A number followed by “r” means opened for reading, “w” means opened for writing, and “u” means read/write access. These letters do not show whether I/O is happening now. A read handle does not prove the entire process or volume has no pending writes. If you see “cwd”, the process has that location as its current working directory, as a Terminal shell can when you navigate to the drive.

Finding out what’s blocking your drive

For ejection problems specifically, you usually just need to know which process names appear. Common culprits include mds and mds_stores (Spotlight indexing), Finder, QuickLookUIService (thumbnail generation), and fsevents (filesystem watcher).

If you see a lot of output and want to narrow it down, you can use grep:

lsof /Volumes/YourDriveName | grep -v "^COMMAND"

This removes the header line so you only see actual processes. If you want just the unique process names:

lsof /Volumes/YourDriveName | awk '{print $1}' | sort -u

Useful flags

The -c flag filters by command name. If you suspect Spotlight is the problem:

lsof -a -c mds /Volumes/YourDriveName

By default, lsof combines selection criteria with OR. Add -a to require both a matching command name and a handle on this volume.

The +D flag recursively lists all open files in a directory:

lsof +D /Volumes/YourDriveName

This walks the directory tree and can be slow on large drives with many files. For a mounted volume, the mount-point form above avoids that recursive scan.

To see which processes a specific user has open on the drive:

lsof -a -u yourusername /Volumes/YourDriveName

Using lsof without sudo

If expected processes or file paths are missing, permissions may be limiting the result. Running with sudo can expose additional information:

sudo lsof /Volumes/YourDriveName

You’ll need to enter your password. macOS privacy permissions can still restrict inspection, even with sudo. An empty result is not proof that the drive is safe to force eject.

Killing the blocking process

Save your work and quit a recognized app normally first. For a process you own and understand, a termination signal is another option:

kill 6789

Replace 6789 with the current PID of that specific process. This signal is not the same as an app’s Quit command and does not guarantee a save prompt. If a recognized app is unresponsive, force termination is a last resort:

kill -9 6789

Force termination prevents cleanup and can lose unsaved work or interrupt writes. Do not use these commands to kill Spotlight, Time Machine, or unfamiliar system services. A service restarting later does not make interrupting it safe.

For applications you own (like a Terminal window with a shell sitting in the drive’s directory), it’s cleaner to just close the application normally or navigate away from the drive before trying to eject.

Common scenarios

Terminal with current directory on the drive: If you’ve cd’d into a folder on your external drive, that shell process will hold the drive open. Either cd somewhere else (cd ~) or close that Terminal window.

Finder windows: If Finder has a window open to the drive, or even if it has the drive selected in the sidebar, it can prevent ejection. Close any Finder windows showing the drive’s contents.

Spotlight indexing: The mds, mds_stores, and mdworker processes index new drives automatically. Wait for indexing to finish. If you do not need Spotlight search on this drive, consider excluding it through Spotlight Privacy, understanding that this changes search behavior. Do not routinely kill the indexing services.

Background apps with files open: Some applications keep recent files referenced even after you’ve closed the documents. Creative applications like Photoshop or video editors are common offenders. Quitting the app entirely usually releases the files.

Beyond the command line

If you’re not comfortable with Terminal or don’t want to puzzle through lsof output every time you need to unplug a drive, there are graphical options.

Activity Monitor can show you open files for a specific process, but you have to already know which process to inspect. It doesn’t easily answer “what’s using this drive?”

Ejecta was built specifically for this problem. Its free diagnosis shows connected drives and detected holders in the menu bar. Paid actions can quit supported apps and retry ejection. It identifies system holders such as Spotlight but does not ordinarily terminate them, and neither its process list nor lsof certifies the absence of writes.

The command line is powerful for those who prefer it, but it shouldn’t be mandatory for something as simple as unplugging a drive.

Ejecta offers free drive diagnosis without a timed trial. The paid license unlocks quit and eject actions for supported apps, Eject All and Time Machine controls. System holders may require waiting, authorization or shutdown. Save work and finish transfers first.

Buy Now - $29 $9.99