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.