English
macOS launchctl Complete Guide: A Powerful Tool for System Service Management

launchctl is a macOS system service management tool used to load, unload, start, and stop Daemon processes (Daemons) and Agents (Agents). It is based on launchd The service management system is one of the core components of macOS.
If you are a macOS developer, operations personnel, or advanced user, master launchctl Allows you to better manage system services and automate tasks.
1. The relationship between launchd and launchctl
launchd: macOS's init system, responsible for loading services during system startup and managing background processes (similar to Linux'ssystemd).launchctl: Command-line tool for use withlaunchdInteraction, management services.
2. launchd service type
| Type | Storage location | Execution permission | Purpose |
|---|---|---|---|
| System Daemons | /System/Library/LaunchDaemons/ | root | System-level background service |
| User Daemons | /Library/LaunchDaemons/ | root | Global services installed by the administrator |
| System Agents | /System/Library/LaunchAgents/ | Current user | User-level services provided by the system |
| User Agents | ~/Library/LaunchAgents/ | Current user | User-defined background tasks |
3. launchctl Basic Usage
3.1 Loading/Unloading Service
bash
# Load service (do not start automatically)
launchctl load /path/to/plist
# Load and start immediately (recommended method, macOS 10.10+)
launchctl bootstrap gui/$UID /path/to/plist
# Older versions of macOS use the -w parameter
launchctl load -w /path/to/plist
# Uninstall service
launchctl unload /path/to/plist
launchctl bootout gui/$UID /path/to/plist # macOS 10.10+3.2 Start/Stop Service
bash
# Start the service (must be loaded first)
launchctl start com.example.service
# Stop service
launchctl stop com.example.service3.3 Check service status
bash
# List all loaded services
launchctl list
# Check the status of a service
launchctl print gui/$UID/com.example.service3.4 Debugging Service
bash
# View logs (in conjunction with the log command)
log stream --predicate 'sender == "com.example.service"'
# Run the service directly (to test whether the configuration is correct)
/path/to/your/daemon -f4. Detailed Explanation of the plist Configuration File
launchd Service usage .plist(Property List) file definition, usually stored in the corresponding Service Catalog Middle.
Example: a simple plist file
xml
<?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>com.example.myapp</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/myapp</string>
<string>--daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/myapp.log</string>
<key>StandardErrorPath</key>
<string>/var/log/myapp.err</string>
</dict>
</plist>Key configuration items description
| Parameters | Explanation |
|---|---|
| Label | Service unique identifier (e.g.com.example.myapp) |
| ProgramArguments | The command to execute (array form) |
| RunAtLoad | Whether to run immediately on load |
| KeepAlive | Automatically restart after crash |
| StartInterval | Scheduled run interval (seconds) |
| StartCalendarInterval | Calendar scheduled run |
| StandardOutPath | Standard output log path |
| StandardErrorPath | Error log path |
4.1 Practical Case: APIServer Backend Service Configuration
The following is used in a real production environment launchd Configuration file, used to manage an API backend service:
xml
<?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>Description</key>
<string>APIServer - Backend Service</string>
<key>Disabled</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>flower.com.apiserver</string>
<key>ProcessType</key>
<string>Background</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/apiserver/apiserver.darwin.amd64</string>
<string>--config-dir</string>
<string>/usr/local/etc/apiserver</string>
<string>--config-name</string>
<string>config.yaml</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/apiserver.log</string>
<key>StandardOutPath</key>
<string>/usr/local/var/log/apiserver.log</string>
<key>Version</key>
<string>v0.1.0</string>
<key>WorkingDirectory</key>
<string>/usr/local/var</string>
</dict>
</plist>Configuration Item Interpretation
| Configuration item | value | Explanation |
|---|---|---|
Label | flower.com.apiserver | Unique service identifier, following the reverse domain name naming convention |
Description | APIServer - 后台服务 | Service description, for easy identification |
ProgramArguments | [/usr/local/bin/apiserver/..., --config-dir, ...] | Complete command-line arguments, supporting passing the configuration file path |
WorkingDirectory | /usr/local/var | Specify the working directory for the service at runtime |
KeepAlive | true | Automatically restart the process when it exits abnormally to ensure high service availability. |
RunAtLoad | true | Starts immediately after the service is loaded, suitable for automatic startup at boot scenarios. |
ProcessType | Background | Mark it as a background process, and the system will give it an appropriate resource scheduling priority. |
Disabled | true | Disabled by default; must be enabled manually (can be done via launchctl enable Enable) |
StandardOutPath/StandardErrorPath | /usr/local/var/log/apiserver.log | Merge standard output and error output into the same log file for unified viewing. |
Usage of this configuration file
bash
# 1. Place the plist file in the corresponding service directory
sudo cp flower.com.apiserver.plist /Library/LaunchDaemons/
# 2. Load and enable the service (Note: Disabled is true, so it needs to be enabled first)
sudo launchctl enable system/flower.com.apiserver
sudo launchctl bootstrap system /Library/LaunchDaemons/flower.com.apiserver.plist
# 3. Check service status
sudo launchctl print system/flower.com.apiserver
# 4. View service logs
tail -f /usr/local/var/log/apiserver.log💡 Note
This service is a system-level daemon (System Daemon), and requires the use of sudo Permission management, and the configuration file should be stored in /Library/LaunchDaemons/ Under the directory.
5. Common real-world use cases
5.1 Boot Autostart Script
bash
# 1. Create a plist file
cat > ~/Library/LaunchAgents/com.example.myscript.plist <<EOF
<?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>com.example.myscript</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>echo "Hello, launchd!" >> ~/mylog.txt</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
# 2. Load and start
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.example.myscript.plist5.2 Scheduled Tasks (Alternative to cron)
xml
<!-- Run once every 1 hour -->
<key>StartInterval</key>
<integer>3600</integer>
<!-- or run at 2:00 AM every day -->
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>0</integer>
</dict>5.3 Managing Homebrew Services
bash
# Homebrew uses launchctl to manage services.
brew services list # View Services
brew services start nginx # Start
brew services stop nginx # Stop6. Common Issues and Debugging Tips
6.1 Difference between launchctl load and bootstrap
load(Old version) andbootstrap(New version) has similar functions, butbootstrapThis is the recommended method (macOS 10.10+).bootoutCorrespondingunload.
6.2 Permission Issues
- System Daemons Need
sudo:
bash
sudo launchctl load /Library/LaunchDaemons/com.example.service.plist- User Agents No root privileges required.
6.3 Debugging Tips
Check plist format:
bash
plutil -lint /path/to/plistView service logs:
bash
tail -f /var/log/system.logForce reload service (use with caution):
bash
sudo launchctl kickstart -k system/com.apple.audio.coreaudiod7. Service Dependency Management
In some scenarios, you may need to ensure that when one service starts, another service is already running successfully. Regarding using in the macOS environment launchctl How to implement service dependencies when managing services, please refer to:Detailed explanation of launchctl service dependency configuration
8. Summary
launchctlis a macOS service management tool, based onlaunchd.through
.plistFile definition service, supports Boot startup, scheduled tasks, process supervision.Recommended to use
bootstrap/bootout(macOS 10.10+)。Pay attention during debugging Permissions, logs, plist syntax.
Master launchctl It can better manage system services and automation tasks, and is suitable for developers, operations and maintenance staff, and advanced users.