Esegui script al logout senza utilizzare il hook di logout


11

Ho cercato di eseguire alcuni comandi di pulizia quando un utente si disconnette, tuttavia la vecchia funzione di hook di logout, sebbene ancora funzionante, è stata deprecata per un po 'di tempo, quindi potrebbe non essere con noi per molto più tempo.

Sfortunatamente, sebbene launchdfornisca una comoda alternativa agli hook di login, non esiste un sostituto così ovvio per gli hook di logout.

Ho già sperimentato la creazione di uno script di shell che viene avviato all'accesso e dorme semplicemente fino a quando non viene ricevuto un segnale di interruzione, tuttavia questo non sembra funzionare (lo script non riceve mai il segnale durante il normale funzionamento).

Altrimenti non sono sicuro di quale sarebbe il modo migliore per eseguire un comando rapido al logout? So che ci sono alcune utility di terze parti che possono farlo, ma c'è un modo "corretto" per farlo più?

Risposte:


7

Sembra che Apple non sia interessata alla sostituzione del gancio di disconnessione, poiché hanno chiuso il mio problema chiedendone uno.

Tuttavia, uno dei miglioramenti in Yosemite è che launchd ora invia correttamente i segnali agli script della shell. Ciò significa che ora puoi eseguire un'attività di disconnessione in questo modo:

Ecco un esempio logout.sh:

#!/bin/sh
onLogout() {
    echo 'Logging out' >> ~/Logs/logout.sh.log
    exit
}

trap 'onLogout' SIGINT SIGHUP SIGTERM
while true; do
    sleep 86400 &
    wait $!
done

Questo semplicemente dormirà (in modo asincrono, facendolo in modo sincrono senza la e commerciale non sembra funzionare) fino a quando non riceve uno dei segnali intrappolati, a quel punto eseguirà la onLogoutfunzione.

Tutto quello che devi fare è avviare quello script usando un RunAtLoadagente di lancio o un demone di avvio e verrà eseguito al log-out o allo spegnimento, anche se è importante tenere presente che le attività hanno solo un tempo limitato per essere completate prima di essere uccise invece , quindi questo non dovrebbe essere usato per eseguire tutto ciò che richiede molto tempo o richiede una connessione di rete che potrebbe essere ritardata ecc.

Naturalmente questo non è di alcuna utilità per nessuno su Mavericks o prima, ma sotto Yosemite ora sembra funzionare come previsto; quindi in realtà lo stavo facendo bene in primo luogo, launchdma non stavo inviando correttamente i segnali :)

NOTA: affinché funzioni gli script di shell sembra che debbano essere eseguiti direttamente dall'avvio, ovvero non dovrebbero essere invocati tramite sh. Quindi, se fosse inserito nel ~/Library/Scripts/foo.shtuo programma gli argomenti potrebbero apparire come:

<key>ProgramArguments</key>
<array>
    <string>~/Library/Scripts/foo.sh</string>
    <string>bar</string>
</array>
<key>EnableGlobbing</key>
<true/>

Quando eseguo questa sceneggiatura, ritorna line 8: syntax error near unexpected token ;'(con una tomba prima del punto e virgola)
Jason,

Spiacenti, hai ragione @Jason, penso di averlo semplificato troppo, l'ho modificato per assomigliare più da vicino a un esempio funzionante.
Haravikk,

Si attiva quando lo scarico usando launchctl, ma non quando esco o riavvio. Perché?
Traliccio

C'è un modo per eseguirlo prima che la rete si interrompa?
Filippo il

2

Puoi usare iHook per eseguire hook di login / logout, che ho trovato ancora funzionanti per hook di login e logout non interattivi scritti in Bash e Python su Yosemite.

http://rsug.itd.umich.edu/software/ihook/


Sfortunatamente questo usa ancora i normali ganci di logout sotto il cofano.
0942v8653,

0

Se altri utenti che arrivano qui dai motori di ricerca non si preoccupano di utilizzare un hook di logout, esegui ad esempio:

sudo defaults write com.apple.loginwindow LogoutHook '~/.logouthook';echo $'#!/usr/bin/env bash\n\nsay a'>~/.logouthook;chmod +x ~/.logouthook

Quindi ~/.logouthookviene eseguito alla successiva disconnessione.

Il valore della LogoutHookchiave deve essere un percorso per un eseguibile e non un comando shell. Il defaultscomando modifica /var/root/Library/Preferences/com.apple.loginwindow.plist.


Grazie per averlo fornito in alternativa, ma la mia preoccupazione è che gli hook di login e logout siano stati deprecati per le ultime versioni di OS X; anche se mi aspetto che funzionino ancora in Yosemite (dal momento che si concentra principalmente sull'interfaccia utente e sui cambiamenti di continuità) sembra che potrebbe andare in qualsiasi momento, come i vecchi elementi di avvio che vengono sostituiti launchd, solo un peccato che non abbia RunBeforeUnloado un'opzione simile .
Haravikk,

0

Non riesco nemmeno a far funzionare l'elemento di log di launchd in 10.10.1, ma la chiave LogoutHook in "com.apple.loginwindow.plist" di root funziona bene. Ci sono altri esempi per il metodo launchd?

Ad ogni modo, ho scritto un AppleScript per eliminare il volume di sistema al logout in modo che il suono di avvio non venga ascoltato al prossimo avvio. Ciò che non ho elaborato sono i dettagli per la gestione di più comandi di logout basati su una singola chiave LogoutHook o se è possibile memorizzare più chiavi LogoutHook, quindi sono ancora interessato al metodo Launchd, che potrebbe essere gestito con Lingon, o anche Lingon 3, che ha un ambito molto più ristretto rispetto all'originale (presumibilmente esistere nell'App Store).

imposta current_Vol su (esegui script di shell "osascript -e \" volume di output di (ottieni impostazioni volume) \ "")
se il pulsante restituito da (visualizza la finestra di dialogo "Desideri silenziare il segnale di avvio, ripristinarlo o annullare?" I pulsanti {"Silenzio", "Ripristina", "Annulla"} pulsante predefinito 1) è "silenzio", quindi
    eseguire lo script di shell "mkdir -p / usr / local / logouttask; echo '#! / bin / bash
# logout script
osascript -e \ "imposta volume 0 \" '> / usr / local / logouttask / logoutscript; sudo impostazioni predefinite scrivi com.apple.loginwindow LogoutHook / usr / local / logouttask / logoutscript; chmod + x / usr / local / logouttask / logoutscript "con privilegi di amministratore
altro
    provare
        eseguire lo script di shell "sudo defaults write com.apple.loginwindow LogoutHook ''; rm / usr / local / logouttask / logoutscript" con privilegi di amministratore
        display dialog "Il suono di avvio verrà ascoltato se l'impostazione del volume è maggiore di 0 allo spegnimento o al riavvio." pulsanti {"OK"} pulsante predefinito 1
    in caso di errore il numero di messaggio_errore il numero_errore
        se error_number è 1 allora
            display dialog "Lo script che imposta il volume di sistema su zero al logout non esiste. Il segnale acustico di avvio verrà ascoltato se l'impostazione del volume è maggiore di 0 all'arresto o al riavvio." pulsanti {"OK"} pulsante predefinito 1
        altro
            visualizza la finestra di dialogo "Errore:" & il numero_errore & "." e i pulsanti messaggio_errore {"OK"} pulsante predefinito 1
        finisci se
    fine prova
finisci se

Come stai invocando l'elemento di logout? Il mio esempio di script di shell per deve essere invocato direttamente (nessun uso di sh), quindi deve essere un file eseguibile, lo noterò nella mia risposta.
Haravikk,

Grazie per l'aggiornamento Ci proverò al più presto e ti farò sapere.
Traliccio

Posso solo attivare l'evento contenuto in foo.sh eseguendo "launchctl unload" sul plist che lo chiama nel Terminale. La disconnessione non lo attiva.
Traliccio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.