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.