To set up the launchd item log in to an admin user account. Use at your own risk.
# LAUNCHD ITEM /usr/bin/sudo /bin/bash -c ' yourname=$(/usr/bin/logname) LaunchdPlistFile="/Library/LaunchDaemons/user.${yourname}.launchd.test.plist" EX_MARK='!' /bin/cat > "${LaunchdPlistFile}" <<-EOF <?xml version="1.0" encoding="UTF-8"?> <${EX_MARK}DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <true/> <key>Debug</key> <true/> <key>UserName</key> <string>${yourname}</string> <key>GroupName</key> <string>${yourname}</string> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin</string> <key>YetAnotherEnvironmentVar</key> <string>/path/to/dir</string> </dict> <key>Label</key> <string>user.${yourname}.launchd.test</string> <key>ProgramArguments</key> <array> <string>/Users/${yourname}/Desktop/launchd_test.sh</string> </array> <key>RunAtLoad</key> <true/> <key>ServiceDescription</key> <string>Test ownership of launchd processes</string> <key>StandardErrorPath</key> <string>/Users/${yourname}/Desktop/launchd_test_error.log</string> <key>StandardOutPath</key> <string>/Users/${yourname}/Desktop/launchd_test.log</string> <key>StartInterval</key> <integer>20</integer> <key>Umask</key> <integer>002</integer> </dict> </plist> EOF ' : <<-'COMMENT' # switch UserName & GroupName <key>UserName</key> <string>${yourname}</string> <key>GroupName</key> <string>${yourname}</string> or <key>UserName</key> <string>root</string> <key>GroupName</key> <string>wheel</string> or ... COMMENT yourname=$(/usr/bin/logname) LaunchdPlistFile="/Library/LaunchDaemons/user.${yourname}.launchd.test.plist" open -e "${LaunchdPlistFile}" # SCRIPT LaunchdTestScript="/Users/${yourname}/Desktop/launchd_test.sh" /bin/cat > "${LaunchdTestScript}" <<-'EOF' #!/bin/bash # /bin/sh # cf. man 5 launchd.plist | less -p 'A daemon or agent launched by launchd SHOULD:' trap '/usr/bin/logger -i "received SIGTERM for launchd test"; exit 1' TERM # write stdout & stderr to console.log in /Library/Logs/Console/ # open -a Console # (requires /bin/bash to work correctly!) #exec >/dev/console 2>&1 echo echo "SYSTEM LOGS:" /usr/bin/logger -i "logger: $0" /usr/bin/syslog -s -l 1 "syslog: $0" echo echo echo 'id:' echo /usr/bin/id | /usr/bin/sed -E \ -e $'s/,? /\\\n/g' \ -e $'/groups=/s/groups=/groups:\\\n/' \ -e 's/=/ = /g' \ -e $'s/[()]/ /g' echo # cf. man mail | less -p HOME # cf. Read local Unix mail in Mail.app, http://codesnippets.joyent.com/posts/show/1392 #export HOME=/Users/$(/usr/bin/whoami) #echo "hello world $(date)" | /usr/bin/mail -s 'test mail' $(/usr/bin/whoami)@localhost echo echo "SHELL: $SHELL" echo "BASH: $BASH" echo echo "current set of shell flags: $-" # cf. help set echo echo "SHELLOPTS: $SHELLOPTS" echo echo 'set:' echo set echo printf "%q %q\n" "IFS:" "$IFS" echo echo 'env:' echo /usr/bin/env echo echo echo 'shopt ... on:' echo shopt | /usr/bin/egrep 'on$' #set -o | /usr/bin/egrep 'on$' echo cd ~ echo "HOME: $PWD" echo echo 'try to cd to /private/var/launchd/0' cd /private/var/launchd/0 return_code=$? echo "cd exit status: ${return_code}" echo if [[ ${return_code} -eq 0 ]]; then echo "ROOT PRIVILEGES"; else echo "NO ROOT PRIVILEGES"; fi echo echo "PPID: $PPID" echo echo "PID: $$" echo echo 'ps -p PID:' echo /bin/ps -p $PPID echo /bin/ps -p $$ echo echo 'lsof -p PID:' echo /usr/sbin/lsof -p $PPID 2>/dev/null echo /usr/sbin/lsof -p $$ 2>/dev/null echo echo "users: $(/usr/bin/users)" echo echo "groups: $(/usr/bin/groups)" # /usr/bin/id -Gn echo echo "logname: $(/usr/bin/logname)" echo echo "whoami: $(/usr/bin/whoami)" # /usr/bin/id -un echo; echo echo "#----------------------------------------------------------------------------------------------- $(date)" echo; echo exit 0 #exit 1 EOF open -e "${LaunchdPlistFile}" open -e "${LaunchdTestScript}" /usr/bin/sudo /usr/sbin/chown root:wheel "${LaunchdPlistFile}" /usr/bin/sudo /bin/chmod 0644 "${LaunchdPlistFile}" /usr/sbin/chown ${yourname}:${yourname} "${LaunchdTestScript}" /bin/chmod u+x "${LaunchdTestScript}" ls -l "${LaunchdPlistFile}" ls -l "${LaunchdTestScript}" # enable launchd item /usr/bin/sudo /bin/launchctl load -w "${LaunchdPlistFile}" 2>/dev/null # disable launchd item /usr/bin/sudo /bin/launchctl unload -w "${LaunchdPlistFile}" 2>/dev/null ls -l /Users/${yourname}/Desktop/launchd_test.log ls -l /Users/${yourname}/Desktop/launchd_test_error.log open -a Console /Users/${yourname}/Desktop/launchd_test.log #/usr/bin/srm -v /Users/${yourname}/Desktop/launchd_test.log open -a Console /Users/${yourname}/Desktop/launchd_test_error.log /usr/bin/sudo /bin/launchctl list /usr/bin/sudo /usr/bin/fs_usage | /usr/bin/egrep -i launchd_test # convert possible tabs to spaces #/usr/bin/expand "${LaunchdPlistFile}" > ~/Desktop/user.${yourname}.launchd.test.plist #open -e ~/Desktop/user.${yourname}.launchd.test.plist man 8 launchd man 5 launchd.plist man 5 launchd.conf man 1 launchctl #---------------------------------------------------------------- # set launchd log level to debug # cf. http://www.puredarwin.org/developers/booting/launchd # sudo launchctl log level debug sudo bash -c 'echo "log level debug" >> /private/etc/launchd.conf' echo 'log level debug' >> ${HOME}/.launchd.conf sudo nano /private/etc/launchd.conf ls -l /private/etc/launchd.conf # send all launchd logging output to /private/var/log/launchd.log # cf. http://developer.apple.com/technotes/tn2004/tn2124.html#SECLAUNCHDLOGGING sudo cp -ip /etc/syslog.conf /etc/syslog.conf-orig (cat /etc/syslog.conf-orig ; echo "launchd.* /var/log/launchd.log" ) | sudo cp /dev/stdin /etc/syslog.conf sudo kill -HUP `cat /var/run/syslog.pid` ls -1 /private/var/log/*log ls -l /private/var/log/launchd.log open -a Console /private/var/log/launchd.log # disable launchd logging # comment out: "log level debug" sudo nano /private/etc/launchd.conf nano ${HOME}/.launchd.conf # comment out: "launchd.* /var/log/launchd.log" sudo nano /private/etc/syslog.conf sudo kill -HUP `cat /var/run/syslog.pid`
Further information on launchd:
- Getting started with launchd
- AFP548: launchd in Depth
- Wikipedia: launchd
- Mac OS Forge: launchd
- PureDarwin: launchd
- Mac OS X Debugging Magic: launchd
- Daemons and Agents
- Daemons and Agents: Execution Contexts
- Daemons and Agents: Hints and Tips
- Mac OS X Server 10.5: Setting a custom umask
- launchd gotcha
- Re: how to run scripts at shutdown - how does launchd shutdown a system?
- Starting PostgreSQL 8.3 through launchd on Mac OS X 10.5.1 Leopard
- The Future of Init, Part IIb: OS X Launchd