Apple - Make a script/app run on logout

Logout hooks were deprecated in 10.4, but they still work as of 10.9.

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

The value of the LogoutHook key can only be a path to an executable and not a shell command. The logout hook is run as root.

The defaults command modifies /var/root/Library/Preferences/com.apple.loginwindow.plist. Adding a LogoutHook key to /Library/Preferences/com.apple.loginwindow.plist doesn't work.

If a logout hook takes long enough to run, a gray screen is shown until the logout hook terminates. There doesn't seem to be any time limit after which logout hooks are forced to terminate.

I haven't figured out any way to run programs on logout reliably with launchd. When I tried trapping signals like EXIT, the code in the trap was only run when I logged out to the login window and not when I shut down or restarted.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>test</string>
  <key>ProgramArguments</key>
  <array>
    <string>bash</string>
    <string>-c</string>
    <string>trap 'echo a>/Users/username/Desktop/a;say a' EXIT;while :;do sleep 10;done</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Actually there is a non-deprecated way to do it:

  1. Open the "Script Editor" app
  2. Paste
    do shell script "PUT YOUR START SCRIPT PATH HERE"
    
    on quit
        do shell script "PUT YOUR STOP SCRIPT PATH HERE"
        continue quit
    end quit
  1. File > Save, Select Application and Stay open after run handler and Save
  2. System Preferences > Users & Groups > Login Items tab > + button
  3. Add the application and mark it as Hidden

To hide it from the Dock:

  1. Right-click the application and select Show package content
  2. Open Info.plist and add
<key>NSUIElement</key>
<string>1</string>