0

I have this line inside a post install Bash script file which runs from within a PKG installer:

launchctl load /Library/LaunchDaemons/com.mycompany.myapp.plist

The PKG correctly installs both the job plist file and the applet which the job calls.

But when I check if the job is loaded in terminal, I get nothing returned by this:

launchctl list | grep mycompany

If I execute the same load command in Terminal, the job is loaded as expected.

Why does the job not get loaded when the script runs?

Jamie Garroch - MVP
  • 2,839
  • 2
  • 16
  • 24
  • When you run `launchctl list` as a normal user, it lists Launch *Agents* running in your user session; to list Launch *Daemons*, run it as root (i.e. `sudo launchctl list`). BTW, `launchctl load` works the same way; if you run it as a normal user, it loads the job as an Agent, but if you run it as root it'll load it as a Daemon. Your package is presumably running its scripts as root (which is what you want), but it can depend on exactly how the package is configured. – Gordon Davisson Mar 10 '21 at 22:00
  • OMG. Light bulb moment @GordonDavisson! If you paste that as the answer I'll mark it as such. Thank you so much. I've been staring at this for a day now as a Office Win dev! – Jamie Garroch - MVP Mar 10 '21 at 22:36

1 Answers1

1

When you run launchctl list as a normal user, it lists Launch Agents running in your user session; to list Launch Daemons, run it as root (i.e. sudo launchctl list).

More details: some of the launchctl subcommands allow you to explicitly specify which domain you want to deal with. For example:

launchctl print system      # Prints Launch *Daemons*
launchctl print user/501    # Prints Launch *Agents* for user #501's session

But the older "legacy" subcommands, like list, load, unload, start, stop, etc predate this convention and use the user ID the command runs as to determine the domain to act on. So for example:

launchctl load /path/to/plist         # Loads the plist as an Agent in my user session
launchctl list                        # Lists Agents in my user session
sudo launchctl load /path/to/plist    # Loads it as a Daemon in the system domain
sudo launchctl list                   # Lists Daemons in the system domain

Your package is presumably running its scripts as root, so it will load the job as a Daemon (which is what you want), but it can depend on exactly how the package is configured.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • Thank you again @GordonDavisson. Super useful. – Jamie Garroch - MVP Mar 11 '21 at 23:23
  • I just discovered that getting to grips with launchctl also requires knowledge of the nuances of locations as per the documentation: `~/Library/LaunchAgents Per-user agents provided by the user. /Library/LaunchAgents Per-user agents provided by the administrator. /Library/LaunchDaemons System wide daemons provided by the administrator. /System/Library/LaunchAgents OS X Per-user agents. /System/Library/LaunchDaemons OS X System wide daemons.` – Jamie Garroch - MVP Apr 05 '21 at 19:26
  • @JamieGarroch-MVP Correct; see my description of the various Library folders [here](https://stackoverflow.com/questions/14286571/what-does-mac-os-library-folder-store). But note that recent versions of macOS allow launch agents (and maybe daemons?) to load from places other than the usual Library subfolders. BTW, if this answered your question, please [mark it as accepted](https://stackoverflow.com/help/accepted-answer). – Gordon Davisson Apr 05 '21 at 23:14
  • After realising in [this subsequent question](https://stackoverflow.com/questions/66969299/how-to-craft-a-macos-launchd-job-that-can-access-the-home-variable) that the applet which the launchd job runs needs access to the $HOME location, I threw the legacy commands in the trash and opted for the new command as follows: `launchctl bootstrap gui/501 ~/Library/LaunchAgents/com.mycompany.myproduct.plist` Marked as accepted (thanks for the reminder!) – Jamie Garroch - MVP Apr 09 '21 at 22:19