Ejecutar script al cerrar sesión sin usar el gancho de cierre de sesión

11

He estado buscando ejecutar algunos comandos de limpieza cuando un usuario cierra la sesión, sin embargo, la antigua función de enlace de cierre de sesión, aunque todavía funciona, ha quedado en desuso por algún tiempo, por lo que es posible que no esté con nosotros por mucho tiempo.

Desafortunadamente, aunque launchdproporciona una alternativa conveniente a los enlaces de inicio de sesión, no existe un reemplazo tan obvio para los enlaces de cierre de sesión.

Ya he experimentado con la creación de un script de shell que se inicia al iniciar sesión, y simplemente duerme hasta que se recibe una señal de apagado, sin embargo, esto no parece funcionar (el script nunca recibe la señal durante el funcionamiento normal).

De lo contrario, no estoy seguro de cuál sería la mejor manera de ejecutar un comando rápido al cerrar sesión. Sé que hay algunas utilidades de terceros que pueden hacerlo, pero ¿hay alguna forma "correcta" de hacerlo?

Haravikk
fuente

Respuestas:

7

Parece que Apple no está interesado en un reemplazo del gancho de cierre de sesión, ya que cerraron mi problema preguntando por uno.

Sin embargo, una de las mejoras en Yosemite es que launchd ahora envía correctamente las señales a los scripts de shell. Lo que esto significa es que ahora puede hacer una tarea de cierre de sesión de esta manera:

Aquí hay un ejemplo 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

Esto simplemente dormirá (asincrónicamente, haciéndolo sincrónicamente sin el ampersand no parece funcionar) hasta que reciba una de las señales atrapadas, en cuyo punto ejecutará la onLogoutfunción.

Todo lo que necesita hacer es iniciar ese script usando un RunAtLoadagente de lanzamiento o demonio de lanzamiento y se ejecutará al cerrar sesión o al apagarse, aunque es importante tener en cuenta que las tareas solo tienen una cantidad limitada de tiempo para completarse antes de que se eliminen. , por lo tanto, esto no debe usarse para ejecutar nada que tarde mucho tiempo o requiera una conexión de red que pueda retrasarse, etc.

Por supuesto, esto no sirve para nadie en Mavericks o antes, pero bajo Yosemite, ahora parece funcionar como se esperaba; así que en realidad lo estaba haciendo bien en primer lugar, launchdsimplemente no estaba enviando las señales correctamente :)

NOTA: Para que esto funcione, los scripts de shell parecen necesitar ejecutarse directamente mediante el lanzamiento, es decir, no deberían invocarse a través de sh. Entonces, si se colocara en ~/Library/Scripts/foo.shsu programa, los argumentos podrían verse así:

<key>ProgramArguments</key>
<array>
    <string>~/Library/Scripts/foo.sh</string>
    <string>bar</string>
</array>
<key>EnableGlobbing</key>
<true/>
Haravikk
fuente
Cuando ejecuto este script, vuelve line 8: syntax error near unexpected token ;'(con una tumba antes del punto y coma)
Jason
Vaya, tienes razón @ Jason, creo que lo simplifiqué demasiado, lo modifiqué para que se parezca más a un ejemplo de trabajo.
Haravikk
Se dispara cuando lo descargo usando launchctl, pero no cuando me desconecto o reinicio. ¿Por qué?
Trellis
¿Hay alguna forma de ejecutarlo antes de que la red se caiga?
filippo
2

Puede usar iHook para ejecutar enlaces de inicio de sesión / cierre de sesión, que he encontrado que aún funcionan para los enlaces de inicio de sesión y cierre de sesión no interactivos escritos en Bash y Python en Yosemite.

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


fuente
Desafortunadamente, este todavía usa ganchos de cierre de sesión normales debajo del capó.
0942v8653
0

Si a otros que llegan aquí desde los motores de búsqueda no les importa usar un enlace de cierre de sesión, ejecute, por ejemplo:

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

Luego ~/.logouthookse ejecuta la próxima vez que cierre sesión.

El valor de la LogoutHookclave tiene que ser una ruta a un ejecutable y no un comando de shell. El defaultscomando se modifica /var/root/Library/Preferences/com.apple.loginwindow.plist.

Lri
fuente
Gracias de todos modos por darlo como alternativa, pero mi preocupación es que los enlaces de inicio y cierre de sesión han quedado en desuso para las últimas versiones de OS X; aunque espero que sigan funcionando en Yosemite (ya que está enfocado principalmente en los cambios de UI y Continuidad) parece que podría funcionar en cualquier momento, como si se reemplazaran los elementos de inicio antiguos launchd, es una pena que no tenga RunBeforeUnloaduna opción similar .
Haravikk
0

Tampoco puedo hacer que el elemento de inicio de sesión de launchd funcione en 10.10.1, pero la clave LogoutHook en "com.apple.loginwindow.plist" de la raíz funciona bien. ¿Hay otros ejemplos para el método launchd?

De todos modos, escribí un AppleScript para eliminar el volumen del sistema al cerrar sesión para que no se escuche el timbre de inicio en el próximo inicio. Lo que no he resuelto son los detalles para administrar múltiples comandos de cierre de sesión basados ​​en una sola tecla LogoutHook, o si es posible almacenar varias claves LogoutHook, por lo que todavía estoy interesado en el método Launchd, que podría administrarse con Lingon, o incluso Lingon 3, que tiene un alcance mucho más limitado que el original (presumiblemente para existir en la tienda de aplicaciones).

establezca current_Vol en (hacer el script de shell "osascript -e \" volumen de salida de (obtener configuración de volumen) \ "")
si el botón devuelto de (muestra el cuadro de diálogo "¿Desea silenciar el timbre de inicio, restaurarlo o cancelar?", los botones {"Silenciar", "Restaurar", "Cancelar"} botón predeterminado 1) son "silenciar" y luego
    hacer script de shell "mkdir -p / usr / local / logouttask; echo '#! / bin / bash
# script de cierre de sesión
osascript -e \ "set volume 0 \" '> / usr / local / logouttask / logoutscript; sudo por defecto escribe com.apple.loginwindow LogoutHook / usr / local / logouttask / logoutscript; chmod + x / usr / local / logouttask / logoutscript "con privilegios de administrador
más
    tratar
        hacer script de shell "valores predeterminados de sudo escribir com.apple.loginwindow LogoutHook ''; rm / usr / local / logouttask / logoutscript" con privilegios de administrador
        diálogo de visualización "Se escuchará el timbre de inicio si la configuración del volumen es mayor que 0 al apagar o reiniciar". botones {"OK"} botón predeterminado 1
    en caso de error el número de mensaje de error el número de error
        si error_number es 1, entonces
            display dialog "El script que establece el volumen del sistema en cero al cerrar sesión no existe. Se escuchará la campana de inicio si la configuración del volumen es mayor que 0 al apagar o reiniciar". botones {"OK"} botón predeterminado 1
        más
            muestra el cuadro de diálogo "Error:" y el número_error & "." y los botones error_message {"Aceptar"} botón predeterminado 1
        terminara si
    intento final
terminara si
Conducción
fuente
¿Cómo invoca el elemento de cierre de sesión? Mi script de shell de ejemplo para debe invocarse directamente (sin uso sh), por lo que debe ser un archivo ejecutable, lo notaré en mi respuesta.
Haravikk
Gracias por actualizar Lo intentaré lo antes posible y te lo haré saber.
Trellis
Solo puedo activar el evento contenido en foo.sh ejecutando "launchctl unload" en el plist que lo llama en Terminal. Cerrar sesión no lo activa.
Enrejado