Como saber em um script de shell se esse script continua após a suspensão?

Como saber em um script de shell se esse script continua após a suspensão?

Eu tenho um script de shell que é executado regularmente via cron/crontab. Coloquei lá um sleepcomando por alguns minutos:

sleep 5m # Waits 5 minutes.

Tenho que fazer isso porque as ações posteriores dependem de um estado consistente de arquivos que precisam ser sincronizados por outros processos (independentes).

Se meu computador estiver voltando do modo de suspensão/suspensão, não quero continuar com a execução do script (pois o computador pode acordar após 4 minutos e 59 segundos, para que os arquivos ainda não estejam sincronizados).

Como posso verificar em um script de shell se o despertar da suspensão ocorreu há mais de 5 minutos?

(a data de /var/log/pm-suspend.lognão parece estar atualizada no meu sistema)

Responder1

Em primeiro lugar, observemos que sleepisso não leva em consideração o tempo suspenso.

Por exemplo, se você executar o comando sleep 5m, suspender o computador e, 4 minutos depois, ativá-lo, o sleepcomando será encerrado 9 minutos após você iniciá-lo. Ele dorme por 5 minutos não suspensos.

Com isso em mente, acho que você não precisa daquele hack que está procurando. Sua pergunta implicava a suposição oposta e incorreta, ou seja, que um sleep 5mcomando pode dormir durante 4 minutos e 59 segundos que o computador passou suspenso e 1 segundo de tempo acordado.


Dito isto, vejamos uma maneira possível de saber se o computador foi suspenso entre dois momentos.

Existem alguns relógios do sistema, conforme descrito no clock_gettime(2)manual.

Uma delas é que CLOCK_MONOTONICisso não conta o tempo suspenso. É um valor em segundos, a partir de algum ponto de partida arbitrário, que expressa a quantidade de tempo que o computador passou realmente acordado.

Existe outro, CLOCK_REALTIMEque expressa a hora do mundo real. No entanto, está sujeito a saltos repentinos se o relógio for ajustado, por isso não é totalmente confiável. Em vez disso, vamos usar CLOCK_BOOTTIME. Este é um valor em segundos, a partir de algum ponto inicial arbitrário (presumivelmente o tempo de inicialização do sistema), incluindo o tempo que o computador ficou suspenso.

Você pode imprimir esses dois valores com comandos como

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

(Há também uma sintaxe mais simples para obter o tempo monotônico. Escolhi deliberadamente a sintaxe que funciona para os dois tipos de relógio.)

Em determinado ponto, consulte esses dois valores e calcule sua diferença. Em algum outro ponto, faça isso novamente.

A diferença entre essas duas diferenças fornece quanto tempo o computador ficou suspenso entre elas. Mais ou menos um pequeno erro de medição, já que os dois valores não podem ser consultados exatamente no mesmo momento.

Responder2

Mão Única

O horário da última retomada deve estar disponível no systemdsistema de diário com algo como:

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

Portanto, você pode atribuir o carimbo de data/hora no short-isoformato a uma variável com algo como:

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

e adicione cinco minutos enquanto o converte para carimbo de data/hora Unix com algo como:

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

e compare/avalie o carimbo de data/hora Unix posterior com algo como (bashsintaxe específica):

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

Outra maneira

Você pode criar seu próprio carimbo de data/hora colocando um arquivo de script no /lib/systemd/system-sleep/diretório usando este modelo:

#!/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

E use uma lógica semelhante à primeira maneira de analisar e avaliar com base no carimbo de data/hora do seu próprio arquivo de log personalizado.

Perceber: Para usar a segunda maneira de executar scripts que precisam/dependem da conectividade de rede, consulte primeiro:A parte de um script relacionada à rede não será executada em /lib/systemd/system-sleep.

informação relacionada