Featured image of post What are launchd agents and daemons on macOS?

What are launchd agents and daemons on macOS?

Understand macOS launchd, agents, daemons, and property list files. Discover how to locate the plist file for a running process.

What is launchd?

launchd is a macOS system service manager that starts, stops, and manages daemons, agents, and other processes. It is the first process the kernel starts and is responsible for starting all other processes on the system.

If you go to Activity Monitor on your Mac and View > All Processes, Hierarchically, you will see that all processes are children of launchd.

The top process name is kernel_task, its child is launchd, and everything else is a child of launchd.

What are launchd agents and daemons?

launchd can start and manage agents and daemons.

Daemons

Daemons are background processes that run without a user interface. They typically start at boot time and run continuously in the background. One example of a daemon is Apple’s timed time synchronization daemon, which maintains system clock accuracy by synchronizing the clock with reference clocks over the network. Another example is a device management daemon, such as Fleet’s orbit, which manages the device’s configuration and security settings.

Agents

Agents are similar to daemons but run in the context of a user session. They are started when a user logs in and can interact with the user interface. Agents are helpful for tasks that need to run in the background but also need to communicate with the user. For example, a security agent can check the system’s state and notify the user if they fail a corporate security policy.

Agents may or may not have a user interface. Many 3rd party agents run in the background and provide a menu bar icon to configure the agent’s behavior.

How are agents and daemons configured with plist?

launchd uses property list (.plist) files to define the configuration of agents and daemons. These files specify the program to run, the arguments to pass, the environment variables to set, and other settings.

Here is an example of a .plist file for a launchd daemon:

<?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>EnvironmentVariables</key>
    <dict>
       <key>ORBIT_ENROLL_SECRET_PATH</key>
       <string>/opt/orbit/secret.txt</string>
       <key>ORBIT_FLEET_URL</key>
       <string>https://dogfood.fleetdm.com</string>
       <key>ORBIT_ENABLE_SCRIPTS</key>
       <string>true</string>
       <key>ORBIT_ORBIT_CHANNEL</key>
       <string>stable</string>
       <key>ORBIT_OSQUERYD_CHANNEL</key>
       <string>stable</string>
       <key>ORBIT_UPDATE_URL</key>
       <string>https://updates.fleetdm.com</string>
       <key>ORBIT_FLEET_DESKTOP</key>
       <string>true</string>
       <key>ORBIT_DESKTOP_CHANNEL</key>
       <string>stable</string>
       <key>ORBIT_UPDATE_INTERVAL</key>
       <string>15m0s</string>
    </dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.fleetdm.orbit</string>
    <key>ProgramArguments</key>
    <array>
       <string>/opt/orbit/bin/orbit/orbit</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/var/log/orbit/orbit.stderr.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/orbit/orbit.stdout.log</string>
    <key>ThrottleInterval</key>
    <integer>10</integer>
</dict>
</plist>

The typical locations for agent and daemon .plist files are:

TypeLocation
User Agents~/Library/LaunchAgents
Global Agents/Library/LaunchAgents
System Agents/System/Library/LaunchAgents
Global Daemons/Library/LaunchDaemons
System Daemons/System/Library/LaunchDaemons

Note: In rare cases, the .plist files may be located in other directories or missing entirely.

How to view the contents of a .plist file

.plist files come in several formats, including binary, XML, and JSON.

You can view the contents of a .plist file using the plutil (property list utility) command. For example:

plutil -p /System/Library/LaunchDaemons/com.apple.analyticsd.plist

plutil can also convert between different .plist formats. For example, to convert a binary .plist file to XML, run:

cp /System/Library/LaunchDaemons/com.apple.analyticsd.plist my.plist
plutil -convert xml1 my.plist

Can I use a .plist file for cron-like scheduling?

Yes, you can use launchd to schedule tasks in a .plist file. launchd is the recommended alternative to cron on macOS. The StartCalendarInterval key specifies when the task should run. For example, to run a task every day at 5 AM, you can add the following to your .plist file:

<key>StartCalendarInterval</key>
<dict>
    <key>Hour</key>
    <integer>5</integer>
    <key>Minute</key>
    <integer>0</integer>
</dict>

How to find the plist file for a running process

Suppose you identified a process running on your Mac from Activity Monitor and want to find the .plist file that started it. The process should be a child of launchd.

To find the identifier of a running process, you can use the launchctl command. The launchctl list command lists all agents and daemons started by the user, while the sudo launchctl list lists all agents and daemons started by the system.

For example, to find the identifier of the process with PID 62303, run:

( /usr/bin/sudo launchctl list; launchctl list ) | grep 62303

The output will show the identifier, such as:

62303   0  com.fleetdm.orbit

You can now look in the standard locations for the com.fleetdm.orbit.plist file. Alternatively, you can use the launchctl dumpstate command to dump the state of all launchd jobs, including the .plist files that started them. For example, in a macOS system with Fleet’s orbit running, you can run:

launchctl dumpstate | grep -B 1 -A 4 -E "active count = [1-9]" | grep com.fleetdm.orbit

And the output will show the path to the .plist file:

system/com.fleetdm.orbit = {
    path = /Library/LaunchDaemons/com.fleetdm.orbit.plist

You can now view the contents of the .plist file to understand how the process was started.

plutil -p /Library/LaunchDaemons/com.fleetdm.orbit.plist

Further reading

Watch the video on launchd agents and daemons, and how to find the plist file for a running process

Note: If you want to comment on this article, please do so on the YouTube video.