On OS X 10.9, I'm running a script (e.g., ~/bin/run.sh
) via my user crontab (added using crontab -e
). This script, under some specific conditions (not related to this question), will run the following command to launch a menubar application:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
When I run this command (either ~/bin/run.sh
or the launchctl
statement above directly) from the command line normally, the menubar item launches fine.
When this command is run via crontab (again, directly or via ~/bin/run.sh
), I receive the message nothing found to load
in the cron output (in my mail).
Question: why does this fail when run via cron but not when run on the command line?
I have tried executing it via cron in the simplest way possible:
* * * * * launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
This doesn't work (I get nothing found to load
).
I have tried emulating the cron environment:
Capturing the cron environment by having this execute in cron:
env > ~/cronenv
Then opening a shell with this environment:
env - `cat ~/cronenv` /bin/sh
And finally running the command:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
It runs find in these conditions (I wouldn't expect it to, if something in the cron environment is the culprit).
I have tried running it from crontab as sudo
. Nope (nothing found to load
).
I have tried running it from crontab with launchctl load -F
and launchctl load -w
. No luck (nothing found to load
).
Permissions on the plist file are:
-rw-r--r-- 1 root wheel 561 Apr 13 20:55 /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
What's going on?
(BTW, I know it may seem silly to run a script with a launchctl job from within cron, but because it is run within a shell script it's prevented from being a 100% launchctl-controlled process.)
Update: as requested here is the script that is being run (I've been calling it ~/bin/run.sh
), the line in question being #29, and here is the contents of the plist.
Update: the specific solution that works for me, based on @mateusz-szlosek's suggestion to use bsexec
, looks like this:
sudo launchctl bsexec "$(ps -axwww | grep Dock | grep -v grep | awk {'print $1'};)" sudo -u $USER launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
The first sudo
is required otherwise the error Couldn't switch to new bootstrap port occurs. The second sudo
is to execute launchctl
as $USER
. The first argument to bsexec
is a parent process ID who's context will be used to launch the new process. $(ps -axwww | grep Dock | grep -v grep | awk {'print $1'};)
returns the pid
of the Dock process, which loads somewhat early in the launchd hierarchy, but under user context.
bsexec
to launch Agent in proper context? Have You checked stackoverflow.com/questions/1106638/… ?cron
has a optionload : be verbose when loading crontab files
. So it's confusinglaunchctl
'sload
options with it's own. Try using $() or ` around the command.~/bin/run.sh
) which contains the launchctl commands.