sesion - ejecutar funcion al cerrar ventana javascript
¿Cómo detectar el cierre del sistema pendiente en Linux? (9)
Estoy trabajando en una aplicación donde necesito detectar un apagado del sistema. Sin embargo, no he encontrado ninguna forma confiable de obtener una notificación sobre este evento.
Sé que en el cierre, mi aplicación recibirá una señal SIGTERM
seguida de un SIGKILL
. ¿Quiero saber si hay alguna forma de consultar si un SIGTERM
es parte de una secuencia de apagado ?
¿Alguien sabe si hay una manera de consultar eso mediante programación (API C)?
Que yo sepa, el sistema no proporciona ningún otro método para consultar un cierre inminente. Si lo hace, eso solucionaría mi problema también. También he estado probando los runlevels
, pero el cambio en los runlevels
de runlevels
parece ser instantáneo y sin advertencias previas.
Creo que lo tengo.
Fuente = https://github.com/mozilla-b2g/busybox/blob/master/miscutils/runlevel.c
Aquí copio parte del código, en caso de que la referencia desaparezca.
#include "libbb.h"
...
struct utmp *ut;
char prev;
if (argv[1]) utmpname(argv[1]);
setutent();
while ((ut = getutent()) != NULL) {
if (ut->ut_type == RUN_LVL) {
prev = ut->ut_pid / 256;
if (prev == 0) prev = ''N'';
printf("Runlevel: prev=%c current=%c/n", prev, ut->ut_pid % 256);
endutent();
return 0;
}
}
puts("unknown");
Cuando el sistema se apaga, se llaman los scripts rc.d
Tal vez pueda agregar un script allí que envíe alguna señal especial a su programa.
Sin embargo, dudo que puedas detener el cierre del sistema de esa manera.
Desde el cierre del hombre:
Si se usa el argumento de la hora, 5 minutos antes de que se apague el sistema, se
/etc/nologin
archivo/etc/nologin
para garantizar que no se permitan más inicios de sesión.
Entonces puedes probar la existencia de /etc/nologin
. No es óptimo, pero probablemente lo mejor que puedes conseguir.
Es un poco difícil pero si el servidor está ejecutando systemd si puede ejecutar
/bin/systemctl list-jobs shutdown.target
... informará ...
JOB UNIT TYPE STATE
755 shutdown.target start waiting <---- existence means shutting down
1 jobs listed.
... si el servidor se apaga o se reinicia (sugerencia: hay un reboot.target si desea buscar específicamente eso)
No obtendrá No jobs running.
Si no se está apagando.
Debe analizar la salida, que es un poco desordenada, ya que systemctl no devuelve un código de salida diferente para los dos resultados. Pero parece razonablemente confiable. Tendrá que estar atento a un cambio de formato en los mensajes si, sin embargo, actualiza el sistema.
Hacer que su aplicación responda de manera diferente a algunas señales SIGTERM que otras parece opaco y potencialmente confuso. Es discutible que siempre deba responder de la misma manera a una señal dada. Agregar condiciones inusuales hace que sea más difícil entender y probar el comportamiento de la aplicación.
Agregar una secuencia de comandos rc que maneje el apagado (mediante el envío de una señal especial) es una forma completamente estándar de manejar este problema; Si esta secuencia de comandos se instala como parte de un paquete estándar ( make install
o rpm / deb packaging), no debería preocuparse por el control de las máquinas de los usuarios.
La respuesta práctica para hacer lo que originalmente quería es que verifique el proceso de cierre (p. Ej., Ps aux | grep "shutdown -h") y luego, si desea asegurarse de verificar los argumentos de la línea de comandos y la hora en que se inició ( por ejemplo, "shutdown -h +240" comenzó a las 14:51 se cerrará a las 18:51).
En el caso general, desde el punto de vista de todo el sistema, no hay forma de hacerlo. Hay muchas maneras diferentes en que puede ocurrir una "parada". Por ejemplo, alguien puede decidir desconectar el enchufe para detener un programa que ahora tiene un comportamiento malo / peligroso en el momento del apagado o un UPS podría enviar un SIGHUP y luego simplemente fallar. Dado que un cierre de este tipo puede ocurrir repentinamente y sin aviso en ninguna parte del sistema, no hay forma de estar seguro de que está bien seguir funcionando después de un ALIMENTACIÓN.
Si un proceso recibe SIGHUP, básicamente debe asumir que pronto sucederá algo más desagradable. Si desea hacer algo especial e ignorar parcialmente SIGHUP, entonces a) necesita coordinarlo con cualquier programa que realice el cierre yb) debe estar preparado para que si algún otro sistema realiza el cierre y lo mate inmediatamente después de un SIGHUP Su software y sus datos sobrevivirán. Escriba la información que tenga y solo continúe escribiendo en archivos de solo anexos con actualizaciones atómicas seguras.
En su caso, estoy casi seguro de que su solución actual (tratar a todos los SIGHUP como un apagado) es la forma correcta de hacerlo. Si desea mejorar las cosas, probablemente debería agregar una función al programa de apagado que realiza una notificación a través de DBUS o algo similar.
No hay manera de determinar si un SIGTERM
es parte de una secuencia de apagado. Para detectar una secuencia de apagado, puede usar las secuencias de comandos rc.d
como ereOn y Eric Sepanson, o usar mecanismos como DBus.
Sin embargo, desde el punto de vista del diseño, no tiene sentido ignorar SIGTERM
incluso si no es parte de un cierre. El propósito principal de SIGTERM
es pedir cortésmente a las aplicaciones que salgan limpiamente y no es probable que alguien con suficientes privilegios emita un SIGTERM
si no quiere que la aplicación salga.
Tal vez un poco tarde. Sí, puede determinar si un SIGTERM está en un proceso de cierre invocando el comando de nivel de ejecución . Ejemplo:
#!/bin/bash
trap "runlevel >$HOME/run-level; exit 1" term
read line
echo "Input: $line"
term.sh
como, digamos, term.sh
y ejecútelo. Al ejecutar killall term.sh
, debería poder ver e investigar el archivo de run-level
en su directorio de inicio. Al ejecutar cualquiera de los siguientes:
sudo reboot
sudo halt -p
sudo shutdown -P
y comparar la diferencia en el archivo. Entonces deberías tener la idea de cómo hacerlo.
Vea man systemctl
, puede determinar si el sistema se está apagando así:
if [ "`systemctl is-system-running`" = "stopping" ]; then
# Do what you need
fi
esto está en bash, pero puedes hacerlo con ''sistema'' en C