looking into various other posts which recommend to use any of the below:
- Reset permissions with Disk Utility
- Add ExitTimeOut = 1 with sudo defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder ExitTimeOut -int 1
- Clean Re-Instal
- ...
- and many other suggestions
I found that nothing worked - my shutdown time was constant at 20 seconds. Within log file /var/log/com.apple.launchd/launchd-shutdown.system.log I always found at the end that the user process com.apple.launchd.peruser.501 was hanging and needed to be killed after the default of 20 seconds. I tested then to log out first, wait 30 seconds and then trigger the shutdown from the logon screen and then it was very fast. I therefore created the following script which solved the problem - it basically does the same as the normal shutdown - send TERM, wait and then KILL the remaining user processes (just faster).
1. Open Terminal and execute following command to create LogoutHook
sudo defaults write com.apple.loginwindow LogoutHook ~/.logouthook
2. Create text file logouthook.txt with the following content (replace <your user-id> with your real user name)
#!/bin/bash
echo $'\n*** Shutdown ***\n' >>/users/<your user-id>/.shutdown.log
date >>/users/<your user-id>/.shutdown.log
echo $'\n all processes \n' >>/users/<your user-id>/.shutdown.log
ps -u <your user-id> >>/users/<your user-id>/.shutdown.log
killall -u <your user-id> -TERM&
sleep 1
echo $'\n 1 second after sending 1st TERM signal \n' >>/users/<your user-id>/.shutdown.log
ps -u <your user-id> >>/users/<your user-id>/.shutdown.log
killall -u <your user-id> -TERM&
sleep 1
echo $'\n 1 second after sending 2nd TERM signal \n' >>/users/<your user-id>/.shutdown.log
ps -u <your user-id> >>/users/<your user-id>/.shutdown.log
killall -u <your user-id> -KILL&
3. In the terminal to rename the file and make it executable
mv logouthook.txt .logouthook
chmod +x ~/.logouthook
The script works perfectly - shutdown time now constantly at 3 seconds - and the processes which ignored the TERM signals are listed in the logfile ~/.shutdown.log - one might use that info for further analysis.
the above works for OSX 10.8, 10.9, 10.10