←→ Underneath: Background Apps · Усі посібники для Mac

Чому програма повертається після перезавантаження Mac

Ви її завершили. Ви навіть примусово завершили її в Моніторі активності. Через дві секунди або після наступного перезавантаження вона знову працює. Щось навмисно її запускає. На Mac це майже завжди launchd.

Коротко: програма має завдання launchd. RunAtLoad запускає його під час кожного входу, а KeepAlive запускає знову щоразу, коли воно зупиняється. Завершення процесу не змінює завдання. Щоб зупинити його назавжди, вимкніть завдання, а не процес.

Що таке launchd

launchd — це перший процес, який запускає macOS (ідентифікатор процесу 1). Він запускає майже все інше. Він читає невеликі файли .plist, які називають завданнями (jobs) і які кажуть, що і коли запускати. Кожне завдання має мітку — унікальне ім’я на кшталт com.google.keystone.agent.

Програми встановлюють завдання в ~/Library/LaunchAgents, /Library/LaunchAgents або /Library/LaunchDaemons чи реєструють їх зсередини власного пакета програми.

Ключі, які повертають програму

Ось типовий агент запуску:

<key>Label</key>
<string>com.example.helper</string>
<key>ProgramArguments</key>
<array>
  <string>/Applications/Example.app/Contents/MacOS/Helper</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
КлючДіяЩо ви бачите
RunAtLoadЗапускає завдання одразу після завантаження, тобто під час кожного входу (агенти) або запуску Mac (демони)Програма є після кожного перезавантаження
KeepAlive = trueПерезапускає процес щоразу, коли той завершуєтьсяПримусове завершення нічого не дає; за кілька секунд вона знову тут
KeepAlive з умовамиПерезапускає лише в певних випадках, наприклад після збою (SuccessfulExit = false) або поки є мережаВона повертається іноді, але не завжди
StartIntervalЗапускає кожні N секундЗ’являється, недовго працює, зникає, і так знову
StartCalendarIntervalЗапускає в задані моменти, як cronЗ’являється щодня в той самий час
WatchPathsЗапускає, коли змінюється файл або папкаЗ’являється після того, як ви робите щось, здавалося б, не пов’язане

launchd чекає близько 10 секунд між перезапусками завдання, яке постійно завершується, тож завдання з KeepAlive може ще й «блимати».

Інші причини, з яких програма повертається

Як визначити, що саме це

  1. Знайдіть мітку завдання. Виконайте launchctl list | grep -i example, підставивши частину назви програми чи імені розробника. Третій стовпець — це мітка.
  2. Прочитайте завдання:
    launchctl print gui/$(id -u)/com.example.helper
    Знайдіть path (файл plist), state, runs (скільки разів воно запускалося) і last exit code. Велика кількість запусків зазвичай означає KeepAlive.
  3. Відкрийте plist і перевірте RunAtLoad, KeepAlive та ключі інтервалів.
  4. Якщо завдання немає, перевірте «Відкривати під час входу» і власні налаштування програми.

Зупинити чи вимкнути

Що ви робитеПовернеться?
Завершуєте або примусово завершуєте процесТак: одразу, якщо є KeepAlive, під час наступного входу, якщо є RunAtLoad
launchctl bootout gui/$(id -u)/labelНе зараз. Так, під час наступного входу, якщо є RunAtLoad
launchctl disable gui/$(id -u)/label + bootoutНі, доки ви не виконаєте launchctl enable
Переносите plist за межі LaunchAgents + bootoutНі, доки ви не повернете його
Вимикаєте в «Дозволити у фоновому режимі»Ні, доки ви знову не увімкнете

Покрокові команди — у посібнику як безпечно вимкнути агенти запуску.

FAQ

Чому процес перезапускається одразу після того, як я завершую його в Моніторі активності?

У його завданні launchd задано KeepAlive. launchd стежить за процесом і запускає його знову, коли той завершується. Зупиніть завдання командою launchctl bootout, а не завершуйте процес.

Що означає RunAtLoad?

RunAtLoad — це ключ у plist-файлі launchd. Якщо він має значення true, launchd запускає завдання одразу після завантаження plist, а для агента запуску це означає — щоразу, коли ви входите в систему.

Що означає KeepAlive?

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

Яка різниця між зупиненням і вимкненням агента запуску?

Зупинення (launchctl bootout) вивантажує завдання до наступного входу або перезавантаження. Вимкнення (launchctl disable або перенесення plist за межі LaunchAgents) не дає йому знову завантажитися після перезавантаження.