13

I would like to run a script as a particular user on startup (not on login). I thought a launchd LaunchDaemon would do it, but 'man launchd' says:

"If you wish your service to run as a certain user, in that user's environment, making it a launchd agent is the ONLY supported means of accomplishing this on Mac OS X. In other words, it is not sufficient to perform a setuid(2) to become a user in the truest sense on Mac OS X."

They aren't kidding--when I try to run my script as a LaunchDaemon it doesn't work. In particular I'm trying to automate some keychain operations using the 'security' command, and it won't let me change the default keychain when I run the script through LaunchDaemon, though the script works fine when run using sudo from a shell.

A LaunchAgent won't work, because the goal is for the proces to run without a user logging in and LaunchAgents only run when someone logs in. I looked at cron and the @reboot directive and that looks promising, but I read that cron is deprecated on OSX.

MDMarra
  • 100,183
  • 32
  • 195
  • 326
Scott Bonds
  • 131
  • 1
  • 3

3 Answers3

14

I had similar problems trying to make a long running process use a default keychain. Essentially LaunchAgent doesn't seem to run in a full login environment for doing the security commands so changing the default keychain doesn't work and comes back with a permissions error on the /Library/Preferences/ directory.

The secret sauce is to add:

<key>SessionCreate</key>
<true/>

to your plist. This is a undocumented feature which will force a proper environment and will enable you to set the default keychain. Credit to joensson on this question for pointing me in the right direction.

Mark Cheverton
  • 241
  • 2
  • 3
  • If I edit my org.apache.httpd.plist to include this, it won't take affect until the system is restarted correct? I can't simply restart apache myself to do this? – atreat May 01 '15 at 17:52
  • This was the piece that I was missing to have the needed Keychain be available **BUT ALSO** had to do a **reboot** because a `launchctl unload` and then `launchctl load` was not sufficient. A full reboot was needed. – Jesse Apr 06 '22 at 16:14
6

Save as a global daemon (/Library/LaunchDaemons) and specify the user with key UserName:

<key>UserName</key>
<string>Put username here</string>
Bruno
  • 161
  • 1
  • 2
1

There are a number of other places where you can hide startup items in OS X (most of which are thoroughly unsupported). I'd try /etc/rc.local; I seem to recall that working in Panther, so there's a possibility it might still work today.

Handyman5
  • 5,177
  • 25
  • 30