Как я могу заставить Mac OS X запускать программу перед выключением?

9

Я пытаюсь заставить Mac OS X сохранить все виртуальные машины VirtualBox при перезагрузке. У меня уже есть скрипт, который делает это, но мне нужна OS X для автоматического запуска этого скрипта перед перезагрузкой.

Когда Mac OS X перезагружается, он запускает / sbin / reboot?

Или как еще этого достичь?

Эндрю Дж. Брем
источник
Двойной вопрос здесь: apple.stackexchange.com/questions/16825/…
michaelmichael,
Это не дубликат. Я не хочу знать, как запустить скрипт или программу при выходе из системы. Я хочу знать, как запустить скрипт или программу при завершении работы.
Эндрю Дж. Брем
1
Вы правы. Не точный дубликат. Ответ в связанном вопросе советует пользователю поместить свой скрипт, /etc/rc.shutdown.localчтобы запустить его при выключении. Похоже, это то, что вы ищете.
Майкл Майкл
Судя по
Эндрю Дж. Брем
Метод rc.shutdown.local не работает.
Эндрю Дж. Брем

Ответы:

5

Хотя Apple рекомендует использовать « launchd », проще всего создать сценарий оболочки, используя, например, пико Terminal:

pico /Users/Shared/logoutHook.sh

Файл может содержать что-то вроде:

#!/bin/bash
say 'Hasta la vista baby!'

Затем дайте права на исполнение:

sudo chmod +x /Users/Shared/logoutHook.sh

Наконец, подключите скрипт к процедуре выхода из системы:

sudo defaults write com.apple.loginwindow LogoutHook /Users/Shared/logoutHook.sh

Если вы запустите другое приложение, поскольку я не проверял это, я думаю, что было бы полезно предупредить себя и вас, что:

  • Нам может потребоваться отключить сигнал выключения, чтобы выполнить то, что мы хотим;

  • Затем отправьте новый (будьте осторожны, чтобы не убить сигнал, отправленный нашим собственным
    сценарием)…


Если вы хотите удалить крючок:

sudo defaults delete com.apple.loginwindow LogoutHook

Если использовать « launchd », идея заключается в том, чтобы захватить сигнал SIGTERM. Посмотрите: /System/Library/LaunchDaemons/com.apple.shutdown_monitor.plist

llange
источник
4

Launchd отправляет раннее предупреждение о завершении работы всем сценариям / демонам, которые имеют подпрограмму StopService () . Это дает вашему процессу больше времени для очистки.

Просто используйте launchd, чтобы запустить скрипт и запускать его в фоновом режиме, пока не пора выходить.

После того, как сервисы, получившие раннее предупреждение, закрываются, все процессы получают SIGTERMсигнал за несколько секунд до того, как SIGKILLих удаляют.

Вы можете создать скрипт, который спит и перехватывает SIGTERM для запуска вашей команды, когда придет время. Вам нужно будет проверить, достаточно ли на практике времени для выполнения команд. Это позволяет избежать небольшого количества кодирования, но не намного - обычно лучше просто сделать демон из сценария оболочки.


С исторической точки зрения - /sbin/rebootи уровни запуска никогда не существовали в Darwin / OS X и rc.shutdownустарели вместе с остальной частью, rcкоторая launchdявляется боссом. Возможно, вы сможете использовать rc.shutdown на тигре или более ранних версиях (в настоящее время у меня нет одного из этих изображений, удобного для проверки). Lion определенно удалил все остатки rc.d и init.d.

Возможно, вы захотите посмотреть , поможет ли в вашей ситуации лунатик . Я не использовал его в течение долгого времени - но это определенно стремится решить вашу дилемму.

bmike
источник
Оказывается, «устарел» означает «не работает». :-(
Эндрю Дж. Брем
Да - предупреждения начались на Тигре, и я предполагаю, что это исчезло с Леопардом - трудно вспомнить со всеми изменениями Льва, бегающими вокруг моего мозга.
bmike
Это действительно усложняет ситуацию и делает Mac OS X очень плохой серверной платформой.
Эндрю Дж. Брем
launchd полностью способен запускать скрипты при выключении. Возможно, я должен отредактировать историю и оставить этот факт более ясным. Каким образом launchd не удается запустить скрипт при выключении?
bmike
Я не знаю, как заставить запускать скрипты запуска при выключении. Я использую launchd для запуска вещей при загрузке.
Эндрю Дж. Брем