http://www.launchd.info/ has some great unofficial documentation for launchd.
Daemons run apart from users, agents run specifically for users.
/System/Library/LaunchDaemons/System/Library/LaunchAgents/Library/LaunchDaemons/Library/LaunchAgents$USER’s $HOME they exist in:
~/Library/LaunchAgentsRead man launchctl for more.
System Preferences → Users & Groups → Login Items
There aren’t many configuration options. Right clicking the listed items will bring up a context menu with a single “Show in Finder” option.
Login items can be added programmatically with osascript, e.g.:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/TextEdit.app", hidden:false}'
More rarely used:
/Library/StartupItems
/System/Library/StartupItems
Applications can also sneak themselves into your kernel extensions.
These are stored in the filesystem at /System/Library/Extensions.
List currently loaded extensions with:
sudo kextstat
Stop one like so:
sudo kextunload -b com.paceap.kext.pacesupport.snowleopard
While you can remove the files from /System/Library/Extensions, it appears that kextunload also causes the extension not to be loaded in future boots.
Based on my Server Fault answer.
To enable one-off logging, without using the filesystem:
sudo launchctl debug service-target --stdout --stderr
sudo is required even if the script in question is not a system agent/daemon.service-target is kind of weird. Supposing the local service is at ~/Library/LaunchAgents/dev.localmon.plist and has the “label” dev.localmon, its service-target is gui/$UID/dev.localmon.
$UID is your user ID, which is just a standard environment variable, so the shell will interpolate it when calling this at the CLIFor that dev.localmon service, the following will pipe the process’s stdout and stderr into the shell the next time (and only the next time) the service starts:
sudo launchctl debug gui/$UID/dev.localmon --stdout --stderr
You must have already called launchctl load ~/Library/LaunchAgents/dev.localmon.plist before starting the debug session.
That command will hang with the open-and-ready TTYs. In another terminal, run:
launchctl start dev.localmon
start is a legacy command and doesn’t use the fancy new service-target notationlaunchctl does not have a reload command for reading changes to a config.plist file.
Instead, you must unload and then load the plist file anew, e.g.:
launchctl unload ~/Library/LaunchAgents/local.ssh-add.plist
launchctl load $_
($_, like !$ refers to the last argument of the previous command)
timestamp hostname com.apple.xpc.launchd\[1] (label[pid]): Service could not initialize: unique-id: xpcproxy + other-pid: 0xd
StandardOutPath and StandardErrorPath files should be user-writable if this is a ~/Library/LaunchAgents/*.plist process.Tilde-expansion (~/Desktop) is a shell feature, and launchd does not implicitly run the program specified in ProgramArguments inside a shell, so you can’t use a tilde there, or in the other configuration values, to refer to the current home directory.
The working directory is always / unless you set it with WorkingDirectory,
even for user agents (in ~/Library/LaunchAgents).
But if you start a bash shell, it will have access to the usual HOME and USER environment variables (among others).
The first string part of ProgramArguments does not have to be an absolute filename,
though that is recommended, since it’s not clear what directories launchd will look in to find the executable a relative filename is referring to (like PATH in a shell).
(Practically speaking, though, it seems that launchd’s “PATH” defaults to /usr/bin:/bin:/usr/sbin:/sbin, i.e., /etc/paths.)
local.ssh-add.plist, to load an SSH key at system startup:
Create a file at ~/Library/LaunchAgents/local.ssh-add.plist:
<?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>local.ssh-add</string>
<key>RunAtLoad</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>ssh-add</string>
<string>/Users/chbrown/.ssh/production-remote.pem</string>
</array>
</dict>
</plist>
Then run:
launchctl load ~/Library/LaunchAgents/local.ssh-add.plist