Su OS X 10.9, sto eseguendo uno script (ad es. ~/bin/run.sh
) tramite il mio crontab utente (aggiunto usando crontab -e
). Questo script, in alcune condizioni specifiche (non correlate a questa domanda), eseguirà il seguente comando per avviare un'applicazione della barra dei menu:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Quando eseguo questo comando (o ~/bin/run.sh
o l'istruzione launchctl
sopra direttamente) dalla riga di comando normalmente, l'elemento barra dei menu si avvia correttamente.
Quando questo comando viene eseguito tramite crontab (di nuovo, direttamente o tramite ~/bin/run.sh
), ricevo il messaggio nothing found to load
nell'output di cron (nella mia posta).
Domanda: perché fallisce quando viene eseguito tramite cron ma non quando viene eseguito sulla riga di comando?
Ho provato a eseguirlo tramite cron nel modo più semplice possibile:
* * * * * launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Questo non funziona (ottengo nothing found to load
).
Ho provato a emulare l'ambiente cron:
-
Catturare l'ambiente cron eseguendo questo in cron:
env > ~/cronenv
-
Quindi apri una shell con questo ambiente:
env - 'cat ~/cronenv' /bin/sh
-
E finalmente eseguendo il comando:
launchctl load /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Viene eseguito il find in queste condizioni (non me lo aspetterei se qualcosa nell'ambiente cron è il colpevole).
Ho provato a eseguirlo da crontab come sudo
. No ( nothing found to load
).
Ho provato a eseguirlo da crontab con launchctl load -F
e launchctl load -w
. Nessuna fortuna ( nothing found to load
).
Le autorizzazioni sul file plist sono:
-rw-r--r-- 1 root wheel 561 Apr 13 20:55 /Library/LaunchAgents/com.opendns.osx.RoamingClientMenubar.plist
Che sta succedendo?
(A proposito, so che può sembrare sciocco eseguire uno script con un processo launchctl da cron, ma poiché viene eseguito all'interno di uno script di shell è impedito di essere un processo controllato al 100% da launchctl.)
Aggiornamento: come richiesto ecco lo script che è in esecuzione (l'ho chiamato ~/bin/run.sh
), la riga in questione è # 29 e ecco il contenuto del plist .
Aggiornamento: la soluzione specifica che funziona per me, basata sul suggerimento di @ mateusz-szlosek di utilizzare bsexec
, ha il seguente aspetto:
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
È richiesto il primo sudo
altrimenti si verifica l'errore Impossibile passare alla nuova porta bootstrap . Il secondo sudo
è di eseguire launchctl
come $USER
. Il primo argomento su bsexec
è un ID processo genitore il cui contesto verrà utilizzato per avviare il nuovo processo. $(ps -axwww | grep Dock | grep -v grep | awk {'print $1'};)
restituisce il pid
del processo Dock, che viene caricato un po 'prima nella gerarchia launchd, ma nel contesto dell'utente.