Команда lsof: пояснення для користувачів Mac

Опануйте команду lsof, щоб дізнатися, які процеси тримають відкриті файли на вашому Mac. Посібник для розробників і досвідчених користувачів.

Ваш зовнішній диск не витягується. macOS видає до нестями розпливчасте повідомлення про те, що «одна або кілька програм можуть його використовувати». Які програми? Він не каже. Ось тут і стає в пригоді lsof.

Назва розшифровується як «list open files» (список відкритих файлів), і вона робить саме це. У системах на основі Unix, як-от macOS, майже все трактується як файл — зокрема мережеві з’єднання, пристрої та дискові томи. Коли ви не можете витягнути диск, lsof точно вкаже, який процес тримає його в заручниках.

Базовий синтаксис

Найпростіший спосіб скористатися lsof для проблем із витягненням:

lsof /Volumes/YourDriveName

Замініть «YourDriveName» на справжню назву вашого диска. Якщо назва містить пробіли, візьміть увесь шлях у лапки:

lsof "/Volumes/My Backup Drive"

Це повертає список кожного процесу, який має відкритий файловий дескриптор на цьому томі. У кожному рядку показано назву процесу, його ідентифікатор (PID), користувача, від імені якого він запущений, та інформацію про конкретний файл, до якого звертаються.

Як читати вивід

Типовий вивід lsof виглядає приблизно так:

COMMAND     PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mds_store  1234   root   4r   REG   1,12   524288  ...  /Volumes/External/.Spotlight-V100/...
Finder     5678   you    3r   DIR   1,12     1024  ...  /Volumes/External

Найважливіші стовпці — це COMMAND (назва процесу), PID (ідентифікатор процесу, який ви використовуватимете, щоб його завершити) і NAME (фактичний шлях до файлу, до якого звертаються).

Стовпець FD показує, як саме використовується файл. Число, після якого стоїть «r», означає доступ на читання, «w» — на запис, а «u» — і на читання, і на запис. Якщо ви бачите «cwd», то процес має це розташування своєю поточною робочою текою. Так буває, коли у вас відкрите вікно Термінала на папці на диску.

Як з’ясувати, що блокує ваш диск

Саме для проблем із витягненням зазвичай достатньо знати, які назви процесів з’являються. Серед поширених винуватців — mds і mds_stores (індексування Spotlight), Finder, QuickLookUIService (створення мініатюр) і fsevents (стеження за файловою системою).

Якщо ви бачите багато виводу й хочете його звузити, скористайтеся grep:

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

Це прибирає рядок заголовка, тож ви бачите лише самі процеси. Якщо вам потрібні лише унікальні назви процесів:

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

Корисні прапорці

Прапорець -c фільтрує за назвою команди. Якщо ви підозрюєте, що проблема в Spotlight:

lsof -c mds /Volumes/YourDriveName

Це показує лише процеси, назви яких починаються з «mds».

Прапорець +D рекурсивно перелічує всі відкриті файли в теці:

lsof +D /Volumes/YourDriveName

Це ретельніше, ніж базовий синтаксис, але може бути повільним на великих дисках із багатьма файлами.

Щоб побачити, які процеси конкретний користувач тримає відкритими на диску:

lsof -u yourusername /Volumes/YourDriveName

Використання lsof без sudo

Типово lsof показує лише процеси, що належать вашому обліковому запису. Системні процеси, запущені від імені root (як-от mds від Spotlight), не з’являться, доки ви не запустите lsof із sudo:

sudo lsof /Volumes/YourDriveName

Потрібно буде ввести пароль. Для усунення проблем із витягненням використання sudo майже завжди необхідне, оскільки системні процеси часто й виявляються тими, що блокують.

Як завершити процес, що блокує

Знаючи ідентифікатор процесу (PID) із виводу lsof, ви можете завершити його:

kill 1234

Замініть 1234 на справжній PID. Якщо це не спрацює, можна зробити це примусово:

kill -9 1234

Будьте обережні з цим. Завершення системних процесів, як-от mds, може спричинити тимчасові проблеми. Зазвичай процес перезапускається автоматично, але ви можете помітити, що Spotlight дивно поводиться протягом хвилини. Завершення програм на кшталт Finder загалом безпечне; macOS перезапустить Finder автоматично.

Для програм, які належать вам (як-от вікно Термінала з оболонкою, що сидить у теці на диску), чистіше просто закрити програму звичним способом або перейти кудись подалі від диска, перш ніж намагатися його витягнути.

Поширені сценарії

Термінал із поточною текою на диску: якщо ви перейшли (cd) до папки на своєму зовнішньому диску, цей процес оболонки триматиме диск відкритим. Або перейдіть кудись інде (cd ~), або закрийте це вікно Термінала.

Вікна Finder: якщо Finder має відкрите вікно на диску чи навіть просто має диск вибраним у бічній панелі, це може заважати витягненню. Закрийте всі вікна Finder, де показано вміст диска.

Індексування Spotlight: процеси mds, mds_stores і mdworker автоматично індексують нові диски. Ви можете дочекатися, поки вони завершаться, вимкнути індексування командою sudo mdutil -i off /Volumes/YourDriveName або завершити їх напряму.

Фонові програми з відкритими файлами: деякі програми тримають посилання на нещодавні файли навіть після того, як ви закрили документи. Творчі програми на кшталт Photoshop чи відеоредакторів — поширені порушники. Повне завершення програми зазвичай вивільняє файли.

Поза межами командного рядка

Якщо вам некомфортно з Терміналом або ви не хочете щоразу розбирати вивід lsof, коли потрібно від’єднати диск, є й графічні варіанти.

Моніторинг системи може показати відкриті файли для конкретного процесу, але ви маєте вже знати, який процес перевіряти. Він не дає простої відповіді на запитання «що використовує цей диск?».

Ejecta створено спеціально для цієї проблеми. Вона показує ваші підключені диски, визначає, які процеси блокують кожен із них, і дає змогу завершити ці процеси одним кліком. По суті, це графічна оболонка для тієї детективної роботи, якої вимагає lsof, плюс кмітливість, щоб безпечно поратися із системними процесами.

Командний рядок потужний для тих, хто його любить, але він не має бути обов’язковим для такої простої дії, як від’єднання диска.

Якщо ви не хочете щоразу користуватися Терміналом, Ejecta покаже вам, який саме процес блокує ваш диск, — і дасть завершити його одним кліком прямо з рядка меню.

Купити — $9.99