Запуск сценария при выходе из системы без использования ловушки выхода

11

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

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

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

В противном случае я не уверен, каким будет лучший способ выполнить быструю команду при выходе из системы? Я знаю, что есть некоторые сторонние утилиты, которые могут это сделать, но есть ли «правильный» способ сделать это больше?

Haravikk
источник

Ответы:

7

Кажется, что Apple не заинтересована в замене хука выхода из системы, так как они закрыли мою проблему, спрашивая об одном.

Однако одно из улучшений в Yosemite заключается в том, что launchd теперь правильно отправляет сигналы в сценарии оболочки. Это означает, что теперь вы можете выполнить задачу выхода из системы следующим образом:

Вот пример logout.sh:

#!/bin/sh
onLogout() {
    echo 'Logging out' >> ~/Logs/logout.sh.log
    exit
}

trap 'onLogout' SIGINT SIGHUP SIGTERM
while true; do
    sleep 86400 &
    wait $!
done

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

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

Конечно, это никому не нужно на Mavericks или ранее, но при Yosemite это теперь, кажется, работает как ожидалось; так что я делал все правильно, во-первых, launchdпросто не отправлял сигналы должным образом :)

ПРИМЕЧАНИЕ. Чтобы это работало, скрипты оболочки, по-видимому, должны выполняться непосредственно при запуске, т. Е. Не вызываться через sh. Так что, если бы он был помещен в ~/Library/Scripts/foo.shвашу программу, аргументы могли бы выглядеть так:

<key>ProgramArguments</key>
<array>
    <string>~/Library/Scripts/foo.sh</string>
    <string>bar</string>
</array>
<key>EnableGlobbing</key>
<true/>
Haravikk
источник
Когда я запускаю этот скрипт, он возвращается line 8: syntax error near unexpected token ;'(с могилой перед точкой с запятой)
Джейсон
Ой, вы правы @Jason, я думаю, что слишком упростил это, я настроил это, чтобы более близко походить на рабочий пример.
Харавикк
Это срабатывает, когда я выгружаю его с помощью launchctl, но не когда я выхожу или перезагружаюсь. Почему?
Треллис
Есть ли способ запустить его до того, как сеть выйдет из строя?
филиппо
2

Вы можете использовать iHook для запуска хуков входа / выхода, которые, как я обнаружил, все еще работают для неинтерактивных хуков входа и выхода, написанных на Bash и Python на Yosemite.

http://rsug.itd.umich.edu/software/ihook/


источник
К сожалению, этот все еще использует нормальные крюки выхода из системы под капотом.
0942v8653 25.10.14
0

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

sudo defaults write com.apple.loginwindow LogoutHook '~/.logouthook';echo $'#!/usr/bin/env bash\n\nsay a'>~/.logouthook;chmod +x ~/.logouthook

Затем ~/.logouthookзапускается при следующем выходе из системы.

Значение LogoutHookключа должно быть путем к исполняемому файлу, а не командой оболочки. Команда defaultsизменяет /var/root/Library/Preferences/com.apple.loginwindow.plist.

LRI
источник
В любом случае, спасибо за то, что вы предоставили его в качестве альтернативы, но меня беспокоит то, что хуки входа и выхода были объявлены устаревшими для последних нескольких версий OS X; хотя я ожидаю, что они все еще функционируют в Yosemite (так как он в основном сфокусирован на изменениях пользовательского интерфейса и непрерывности), похоже, что он может работать в любое время, например, когда заменяются старые элементы автозагрузки launchd, просто позор, которого нет RunBeforeUnloadили подобная опция ,
Харавикк
0

Я не могу заставить работать элемент logd запуска в 10.10.1, но ключ LogoutHook в корневом каталоге com.apple.loginwindow.plist работает хорошо. Есть ли другие примеры для метода launchd?

Во всяком случае, я написал AppleScript для уничтожения системного тома при выходе из системы, чтобы при следующем запуске не прозвучал сигнал запуска. Что я не разработал, так это подробности управления несколькими командами выхода из системы на основе одного ключа LogoutHook или возможности хранения нескольких ключей LogoutHook, поэтому я по-прежнему заинтересован в методе Launchd, которым можно управлять с помощью Lingon, или даже Lingon 3, который имеет гораздо более узкую область применения, чем оригинал (предположительно, существует в магазине приложений).

установите current_Vol в (сделать скрипт оболочки "osascript -e \" для выходного тома (получить настройки громкости) \ "")
если кнопка возвращена из (отображается диалоговое окно «Хотите отключить звуковой сигнал при запуске, восстановить его или отменить?», кнопки {«Silence», «Restore», «Cancel»} кнопка по умолчанию 1) имеют значение «silence», то
    сделать сценарий оболочки "mkdir -p / usr / local / logouttask; echo '#! / bin / bash
# скрипт выхода
osascript -e \ "установить громкость 0 \" '> / usr / local / logouttask / logoutscript; по умолчанию sudo write com.apple.loginwindow LogoutHook / usr / local / logouttask / logoutscript; chmod + x / usr / local / logouttask / logoutscript "с правами администратора
еще
    пытаться
        сделать сценарий оболочки "sudo по умолчанию написать com.apple.loginwindow LogoutHook ''; rm / usr / local / logouttask / logoutscript" с правами администратора
        отобразить диалоговое окно «Звуковой сигнал при запуске будет слышен, если настройка громкости больше 0 при выключении или перезагрузке». кнопки {"ОК"} кнопка по умолчанию 1
    в случае ошибки номер сообщения об ошибке номер_ошибки
        если error_number равен 1, то
            отобразить диалоговое окно «Сценарий, который устанавливает системную громкость на ноль при выходе из системы, не существует. Звуковой сигнал при запуске будет слышен, если настройка громкости больше 0 при выключении или перезапуске». кнопки {"ОК"} кнопка по умолчанию 1
        еще
            отобразить диалоговое окно «Error:» & номер_ошибки & «.» & кнопки error_message {«OK»} кнопка по умолчанию 1
        конец, если
    конец попробовать
конец, если
шпалера
источник
Как вы вызываете пункт выхода? Мой пример сценария оболочки для должен быть вызван напрямую (без использования sh), так что это должен быть исполняемый файл, я отмечу это в своем ответе.
Харавикк
Спасибо за обновление. Я постараюсь как можно скорее и дам вам знать.
Треллис
Я могу только вызвать событие, содержащееся в foo.sh, запустив "launchctl unload" в списке, который вызывает его в Terminal. Выход из системы не вызывает его.
Треллис