En OS X 10.9, estoy ejecutando un script (por ejemplo, ~/bin/run.sh
) a través de mi usuario crontab (agregado usando crontab -e
). Este script, bajo algunas condiciones específicas (no relacionadas con esta pregunta), ejecutará el siguiente comando para iniciar una aplicación de barra de menú:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Cuando ejecuto este comando (ya sea directamente ~/bin/run.sh
o la instrucción launchctl
que aparece arriba) directamente desde la línea de comandos, el elemento de la barra de menús se inicia correctamente.
Cuando este comando se ejecuta a través de crontab (nuevamente, directamente o vía ~/bin/run.sh
), recibo el mensaje nothing found to load
en la salida 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 intentado ejecutarlo a través de cron de la manera más sencilla posible:
* * * * * launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Esto no funciona (obtengo nothing found to load
).
He intentado emular el entorno cron:
-
Capturando el entorno cron haciendo que esto se ejecute en cron:
env > ~/cronenv
-
Luego abriendo un shell con este entorno:
env - 'cat ~/cronenv' /bin/sh
-
Y finalmente ejecutando el comando:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Se ejecuta el hallazgo en estas condiciones (no lo esperaría, si el culpable es algo en el entorno cron).
He intentado ejecutarlo desde crontab como sudo
. No ( nothing found to load
).
He intentado ejecutarlo desde crontab con launchctl load -F
y launchctl load -w
. Sin suerte ( nothing found to load
).
Los permisos en el 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 cron, pero debido a que se ejecuta dentro de un script de shell se evita que sea un proceso controlado al 100% por launchctl).
Actualización: según lo solicitado aquí está el script que es se está ejecutando (lo he estado llamando ~/bin/run.sh
), la línea en cuestión es # 29, y aquí está el contenido de la lista .
Actualización: la solución específica que me funciona, basada en la sugerencia de @ mateusz-szlosek de usar bsexec
, tiene este aspecto:
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
Se requiere el primer sudo
; de lo contrario, se produce el error No se pudo cambiar al nuevo puerto de arranque . El segundo sudo
es ejecutar launchctl
como $USER
. El primer argumento de bsexec
es un ID de proceso principal cuyo contexto se utilizará para iniciar el nuevo proceso. $(ps -axwww | grep Dock | grep -v grep | awk {'print $1'};)
devuelve el pid
del proceso Dock, que se carga un poco al principio de la jerarquía launchd, pero en el contexto del usuario.