Trying to delay script execution - does not work as expected

Inside a script, I tried to delay the execution of a command with sleep 4h however after ~4.5h the command still had not executed.

Of course I haven’t used the phone the whole time, I set it aside almost immediately after launching the script (with nohup via ssh).

ps, top and htop show that the script is still sitting there, and sleep is still active as if no time had passed at all. This is, btw, the busybox version of sleep (and yes, it accepts s, m, h and d suffixes).

Is this expected behavior, possibly caused by the phone going into deep sleep?

How can I delay script execution by a set time? I could try creating ad-hoc systemd timers, but it feels hacky (I want this to be configurable - it’s about delayed sending of SMS).

Just a tip: the “at” command.
(It’s not sleep replacement, so You need to restructure Your code, and requires atd service)

I’ve noticed the same – or used to be, cannot reproduce just now with

nohup sh -c 'while sleep 5; do date; done' &

… which raises interesting guestion – what version of SailfishOS are
you running – and could it have been changed before the latest version.

(i recall it was easy to reproduce and I recall w/ devel-su I could circumvent)

(for reference I found old log (2023-07-18) where I used sleep(5) in a python
program between polls to ‘/sys/class/power_supply/BAT0/current_now’:

'18/23:04:46' -302 mA
'18/23:04:56' -379 mA
'18/23:05:12' -465 mA
'18/23:05:21' -252 mA
'18/23:05:47' -197 mA

not exactly 5s – I rerun that prog to get results w/ current date and OS version, we’ll see in couple of hours, but not just now)

EDIT: (couple of hours later…) If not charging and screen shutdown, then the sleep “timeout” is ~6 times more than given, in both cases – with sleep(1) in shell script and with time.sleep() in python – have to try what that mce-tools next…

Configure following state and then check again:

# Install mce-tools package, if not already
# Check the current state
/usr/sbin/mcetool |grep suspend
# Set suggested state
/usr/sbin/mcetool -searly
# Test your script

IMO, yes: When the device is in power-save mode, IIRC no time passes (from the perspective of user space code running on that device). Consequently classic UNIX methods as sleep and at commands as well as cron jobs do not work as usual. Using anacron may work, if the script in question is nothing you want to work for many users (IIRC anacron is available at OpenRepos and/or SailfishOS:Chum).

In think systemd is the right tool for this: Either a parametrised systemd-unit or a systemd-timer.

Cronjobs are your friends

w/ systemd something like:

systemd-run --user --unit=xyz --on-active=1m sh -c 'date > /tmp/xyz'

works (just tried; note: -u xyz does not work (as replacement for --unit=xyz))

and with that,

systemctl --user list-timers --all

shows the started timer (and its disappearance after timeout and execution)

also,

systemd-run --user --unit=xyz --on-active='4h 30m' sh -c 'date > /tmp/xyz'

started the unit w/ expected timeout. now figuring out how to cancel…

systemctl --user stop xyz.timer

stopped (and removed it from listing)

better read man systemd-run for more options (and perhaps see what pwd and env outputs (in place of date above))

EDIT: as it often happens the unit returns nonzero – then one cannot
rerun with the same unit (just learned)
– in that case, systemctl --user reset-failed [unit] helps

(couple of months ago I spent quite a lot of time trial-&-erroring many
ways to get some things done w/ systemd – that is the source of my
information, and, like the old good “savonian” way, the responsibility
or understanding the quality of the above is with reader, not me :D)

2 Likes

systemd-run --user --unit=xyz --on-active=1m sh -c 'date > /tmp/xyz'

This essentially creates an ad-hoc timer/service? Looks like just what I need!

Thanks for all the tips alround! Almost missed most of them. I will return after testing.