Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Test ownership of launchd processes (See related posts)

The following launchd item will execute a simple script every 20 seconds to test or show the ownership of the processes executed by the script. In addition, the script will print out the names and values of its shell environment variables.

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


You need to create an account or log in to post comments to this site.