¿Cómo saber en un script de shell si este script continúa después de la suspensión?

¿Cómo saber en un script de shell si este script continúa después de la suspensión?

Tengo un script de shell que se ejecuta de forma regular a través de cron/crontab. Puse allí un sleepcomando durante unos minutos:

sleep 5m # Waits 5 minutes.

Tengo que hacerlo porque las acciones que vienen después dependen de un estado consistente de los archivos que deben ser sincronizados por otros procesos (independientes).

Si mi computadora vuelve del modo de suspensión/suspensión, no quiero continuar con la ejecución del script (ya que la computadora podría reactivarse después de 4 minutos y 59 segundos, por lo que los archivos aún no están sincronizados).

¿Cómo puedo comprobar en un script de shell que el despertar de la suspensión se produjo hace más de 5 minutos?

(la fecha de /var/log/pm-suspend.logno parece estar actualizada en mi sistema)

Respuesta1

En primer lugar, cabe señalar que sleepno se tiene en cuenta el tiempo de suspensión.

Por ejemplo, si ejecuta el comando sleep 5m, luego suspende la computadora, luego 4 minutos más tarde la reactiva y el sleepcomando finalizará 9 minutos después de que lo inició. Duerme 5 minutos sin suspender.

Con esto en mente, no creo que necesites ese truco que estás buscando. Su pregunta implicaba la suposición inversa e incorrecta, es decir, que un sleep 5mcomando puede dormir durante 4 minutos y 59 segundos que la computadora pasó suspendida y 1 segundo de tiempo de vigilia.


Dicho esto, veamos una posible forma de saber si la computadora ha estado suspendida entre dos momentos.

Hay un par de relojes del sistema, como se describe en el clock_gettime(2)manual.

Una es que CLOCK_MONOTONICesto no cuenta el tiempo suspendido. Es un valor en segundos, desde algún punto de partida arbitrario, que expresa la cantidad de tiempo que la computadora pasó realmente despierta.

Hay otro CLOCK_REALTIMEque expresa el tiempo del mundo real. Sin embargo, es propenso a sufrir saltos repentinos si se ajusta el reloj, por lo que no es totalmente confiable. En su lugar, usemos CLOCK_BOOTTIME. Este es un valor en segundos, desde algún punto de partida arbitrario (presumiblemente el tiempo de inicio del sistema), incluido el tiempo que la computadora estuvo suspendida.

Puede imprimir estos dos valores con comandos como

python3 -c 'import time; print(time.clock_gettime(time.CLOCK_MONOTONIC))'
python3 -c 'import time; print(time.clock_gettime(time.CLOCK_BOOTTIME))'

(También hay una sintaxis más simple para obtener la hora monótona; elegí deliberadamente la sintaxis que funciona para ambos tipos de relojes).

En cierto momento, consulte estos dos valores y calcule su diferencia. En otro momento, haz esto de nuevo.

La diferencia entre esas dos diferencias te da la cantidad de tiempo que la computadora estuvo suspendida en el medio. Más o menos un pequeño error de medición, ya que los dos valores no se pueden consultar exactamente en el mismo momento.

Respuesta2

De una sola mano

La hora del último currículum debe estar disponible a través del systemdsistema de diario con algo como:

journalctl -r | awk '/resume/ {print $0; exit}'

Por lo tanto, puedes asignar la marca de tiempo en short-isoformato a una variable con algo como:

lr="$(journalctl -r -o short-iso | awk '/resume/ {printf "%s", $1; exit}')"

y agréguele cinco minutos mientras lo convierte a una marca de tiempo de Unix con algo como:

lr5="$(date -d "$lr + 5 minutes" +'%s')"

y comparar/evaluar la marca de tiempo Unix posterior a la actual con algo como (bashsintaxis específica):

if [[ "$(date +'%s')" -ge "$lr5" ]]
  then
    echo "Five minutes have passed since last resume."
    # Your command/s here
    fi

De otra manera

Puede crear su propia marca de tiempo colocando un archivo de script en el /lib/systemd/system-sleep/directorio usando esta plantilla:

#!/bin/sh

case "${1}" in
  pre)
    # Command(s)/script(s) to execute before system goes to sleep/hibernate
    # nothing
      ;;
  post)
    # Command(s)/script(s) to execute after system wakes up from sleep/hibernate
    # Save your timestamp e.g.:
    # /bin/date +'%s' > /home/user/timestamp.log
      ;;
esac

Y utilice una lógica similar a la primera forma de analizar y evaluar en función de la marca de tiempo de su propio archivo de registro personalizado.

Aviso: Para utilizar la segunda forma de ejecutar scripts que necesitan o dependen de la conectividad de red, consulte primero:La parte de un script relacionada con la red no se ejecutará en /lib/systemd/system-sleep.

información relacionada