Every macOS user has encountered this situation: you right-click an external drive and select "Eject," only to get the frustrating "Disk Not Ejected Properly" message because some process is holding files open. Forcing ejection risks data corruption, especially when dealing with important storage devices.
The most reliable method uses the lsof
(list open files) command in Terminal. Here's the complete solution:
# First, identify your disk's mount point diskutil list # Then run lsof against that mount point lsof +D /Volumes/YourDriveName
Example output will show processes with open file handles:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mds 123 root 24r DIR 1,12 1024 2 /Volumes/BackupDrive Adobe_CC 456 user txt REG 1,12 123456 789 /Volumes/BackupDrive/Project/file.psd
For more detailed analysis, combine lsof with other UNIX tools:
# Find all processes accessing the volume lsof +f -- /Volumes/YourDriveName | awk '{print $1,$2}' | sort | uniq # Get full process tree information ps auxwww | grep [PID_from_lsof]
Create a bash function for your .zshrc or .bash_profile:
function find_disk_users() { if [ -z "$1" ]; then echo "Usage: find_disk_users /Volumes/DriveName" return 1 fi echo "Processes using $1:" lsof +D "$1" | awk 'NR==1 || !/^COMMAND/ {print $1,$2,$9}' | sort | uniq } function safe_eject() { find_disk_users "$1" read -p "Kill these processes? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then lsof +D "$1" | awk 'NR>1 {print $2}' | xargs kill -9 diskutil eject "$1" fi }
For those preferring graphical tools:
- Use Activity Monitor's "Disk" tab
- Try third-party utilities like What's Keeping Me or Ejector
To avoid this issue in development environments:
# For Node.js projects process.on('SIGINT', () => { // Clean up file handles db.close() fs.closeSync(fd) process.exit() })
Remember that some macOS services (like Spotlight or Time Machine) may periodically access drives. Consider temporary disabling them before maintenance:
# Disable Spotlight indexing sudo mdutil -i off /Volumes/YourDriveName
Many macOS users encounter the frustrating situation where they can't safely eject an external drive because the system claims it's "in use." This commonly occurs when:
- Running Time Machine backups
- Having open files in applications like Photoshop or Final Cut Pro
- Background processes accessing the drive
- Spotlight indexing in progress
The most reliable way to identify processes accessing your drive is through the command line. Open Terminal and run:
lsof | grep "/Volumes/YourDriveName"
Replace "YourDriveName" with your actual volume name. This will output all processes with open file handles to that volume.
A typical output looks like:
Photoshop 1234 username txt REG 1,4 2147483648 123456789 /Volumes/ExtDrive/Project.psd
Key columns to note:
- Column 1: Process name
- Column 2: Process ID (PID)
- Last column: Accessed file path
For frequent use, create a shell script:
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 /Volumes/DriveName"
exit 1
fi
lsof | grep "$1" | awk '{print $1, $2}' | sort | uniq -c | sort -nr
Save as find_drive_users.sh
, make executable with chmod +x
, then run with your volume path.
For those preferring graphical tools:
- Open Activity Monitor
- Go to the Disk tab
- Sort by "Bytes Written" or "Bytes Read"
- Look for processes with significant activity
Once you've identified the PID, you can:
- Gracefully quit the application normally
- Force quit using:
kill -9 PID
(use cautiously) - For system processes:
sudo kill -9 PID
Consider these preventive measures:
# Disable Spotlight indexing for external drives
sudo mdutil -i off /Volumes/DriveName
# Create an eject alias that checks first
alias safe_eject='lsof /Volumes/DriveName >/dev/null 2>&1 || diskutil eject /Volumes/DriveName'
If you must force eject, first unmount as safely as possible:
diskutil unmount force /Volumes/DriveName
Then physically disconnect. Run disk repair afterward:
diskutil verifyVolume /Volumes/DriveName
diskutil repairVolume /Volumes/DriveName