launchctl error "no se encontró nada para cargar" cuando se ejecuta a través de cron

0

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:

  1. Capturando el entorno cron haciendo que esto se ejecute en cron:

    env > ~/cronenv
    
  2. Luego abriendo un shell con este entorno:

    env - 'cat ~/cronenv' /bin/sh
    
  3. 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.

    
pregunta Quinn Comendant 11.07.2015 - 08:18

1 respuesta

1

El problema es el contexto de ejecución y el arranque de máquina en OS X (más información en documentación de Apple que vale la pena leer). Es necesario simular la ejecución desde el contexto adecuado. En OS X se hace usando el comando launchctl bsexec . De la respuesta de TheDarkKnight a la pregunta de Iniciar / detener un agente launchd para todos los usuarios con sesiones de GUI tiene:

  

Agentes de descarga

#!/bin/bash
for id in 'ps aux | grep -v grep | grep MyAgent | awk {'print $2'}'
do
    launchctl bsexec $id launchctl unload /Library/LaunchAgents/myAgent.plist
done
     

Reemplace MyAgent con el nombre de su agente de lanzamiento.

     

Agentes de carga

#!/bin/bash
for pid_uid in $(ps -axo pid,uid,args | grep -i "[l]oginwindow.app" | awk '{print $1 "," $2}'); do

    pid=$(echo $pid_uid | cut -d, -f1)
    uid=$(echo $pid_uid | cut -d, -f2)

    launchctl bsexec "$pid" chroot -u "$uid" / launchctl load /Library/LaunchAgents/myAgent.plist
done

En OS X 10.11 y versiones posteriores

Del comentario de vrrathod sobre OS X 10.11, El Capitain, use:

launchctl bootstrap gui/$uid /Library/LaunchAgents/myAgent.plist
    
respondido por el Mateusz Szlosek 11.08.2015 - 21:11

Lea otras preguntas en las etiquetas