En OS X 10.9, estoy ejecutando un script (por ejemplo, ~/bin/run.sh
) a través de mi crontab de usuario (añadido con crontab -e
). Este script, bajo algunas condiciones específicas (no relacionadas con esta pregunta), ejecutará el siguiente comando para lanzar una aplicación de la barra de menús:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Cuando ejecuto este comando (ya sea ~/bin/run.sh
o el launchctl
directamente) desde la línea de comandos normalmente, el elemento de la barra de menús se lanza bien.
Cuando este comando se ejecuta a través de crontab (de nuevo, directamente o a través de ~/bin/run.sh
), recibo el mensaje nothing found to load
en la salida del cron (en mi correo).
Pregunta: ¿por qué falla esto cuando se ejecuta a través de cron pero no cuando se ejecuta en la línea de comandos?
He probado a ejecutarlo vía cron de la forma más sencilla posible:
* * * * * launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Esto no funciona (obtengo nothing found to load
).
He probado a emular el entorno cron:
-
Capturar el entorno cron haciendo que esto se ejecute en cron:
env > ~/cronenv
-
A continuación, abrir un shell con este entorno:
env - `cat ~/cronenv` /bin/sh
-
Y finalmente ejecutar el comando:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Se ejecuta encontrar en estas condiciones (yo no esperaría que, si algo en el entorno de cron es el culpable).
He probado a ejecutarlo desde crontab como sudo
. No ( nothing found to load
).
He probado a ejecutarlo desde crontab con launchctl load -F
y launchctl load -w
. No hubo suerte ( nothing found to load
).
Los permisos del archivo plist son:
-rw-r--r-- 1 root wheel 561 Apr 13 20:55 /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
¿Qué está pasando?
(BTW, sé que puede parecer una tontería ejecutar un script con un trabajo launchctl desde dentro de cron, pero como se ejecuta dentro de un shell script se evita que sea un proceso 100% controlado por launchctl).
Actualización: según lo solicitado aquí está el script que se está ejecutando (lo he llamado ~/bin/run.sh
), siendo la línea en cuestión la número 29, y este es el contenido del plist .
Actualización: la solución específica que me funciona, basada en la sugerencia de @mateusz-szlosek de utilizar bsexec
se ve así:
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
La primera sudo
es necesario, de lo contrario, el error No se puede cambiar al nuevo puerto de arranque ocurre. El segundo sudo
es ejecutar launchctl
como $USER
. El primer argumento para bsexec
es un ID de proceso padre cuyo contexto se utilizará para lanzar el nuevo proceso. $(ps -axwww | grep Dock | grep -v grep | awk {'print $1'};)
devuelve el pid
del proceso Dock, que se carga algo antes en la jerarquía launchd, pero bajo el contexto del usuario.