Score:1

How to tell in a shell script whether this script is continued after suspend?

cn flag

I have a shell script that gets executed on a regular base via cron/crontab. I put there a sleep command for some minutes:

sleep 5m # Waits 5 minutes.

I have to do so because the actions that come afterwards depend on a consistent state of files that need to be synchronized by other (independent) processes.

If my computer is coming back from sleep/suspended mode, I do not want to continue with the execution of the script (as the computer could just wake up after 4 minutes and 59 seconds, so that the files are not yet synchronized).

How can I check in a shell script that the awaking from suspend is more than 5 minutes ago?

(the date of /var/log/pm-suspend.log does not seem to be updated on my system)

in flag
`pm-suspend.log` will only be updated if you’re using `pm-suspend`. This command may give you what you are looking for: `cat /var/log/syslog | grep -a 'systemd-sleep' | grep "Entering sleep state\|System returned from sleep"`.
Score:1
cn flag

First and foremost, let's note that sleep does not take suspended time into account.

For example, if you execute the command sleep 5m, then suspend the computer, then 4 minutes later wake it up, then the sleep command will terminate 9 minutes after you started it. It sleeps for 5 non-suspended minutes.

With this in mind, I don't think you need that hack at all that you're looking for. Your question implied the opposite, incorrect assumption, namely that a sleep 5m command can sleep through 4 minutes and 59 seconds that the computer spent suspended and 1 second of awake time.


That being said, let's look at one possible way of telling if the computer has been suspended between two moments.

There are a couple of system clocks, as described in the clock_gettime(2) manual.

One is CLOCK_MONOTONIC, this does not count suspended time. It's a value in seconds, from some arbitrary starting point, expressing the amount of time the computer spent actually awake.

There is another one, CLOCK_REALTIME which expresses the real world's time. However, it's prone to sudden jumps if the clock is adjusted, so isn't fully reliable. Instead, let's use CLOCK_BOOTTIME. This is a value in seconds, from some arbitrary starting point (presumably the boot time of the system), including the time the computer spent suspended.

You can print these two values with commands like

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

(There's also a simpler syntax to get the monotonic time, I deliberately picked the syntax that works for both kinds of clocks.)

At certain point, query these two values and compute their difference. At a certain other point do this again.

The difference between those two differences gives you the amount of time the computer was suspended in between. Give or take a little measurement error, since the two values can't be queried at the exact same moment.

Score:1
jp flag

One way

Last resume time should be available via systemd journal system with something like:

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

Therefore, you can assign the timestamp in short-iso format to a variable with something like:

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

and add five minutes to it while converting it to Unix timestamp with something like:

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

and compare/evaluate the later to current Unix timestamp with something like (bash specific syntax):

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

Another way

You can create your own timestamp by placing a script file under the /lib/systemd/system-sleep/ directory using this template:

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

And use a logic similar to the first way to parse and evaluate based on the timestamp from your own custom log file.

Notice: For using the second way to run scripts that need/rely on network connectivity, please see first: Network related part of a script will not run in /lib/systemd/system-sleep.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.