Android stops/pauses execution of my background script? Short version:
Why is my bash script (running in the background, started via SSHD) not running every ~30 seconds when it should? (NOTE: SSHD and the script are running as root!)

I have a script that I start using nohup bash script.sh &amp; so that it runs in the background.
The script is supposed to check whether a specific app is connected using netstat and if not it automatically reconnects using am start and input keyevent. (This turns out to be irrelevant though).
I've noticed that even though the script should check every 30 seconds (roughly of course), sometimes it takes minutes to check. I couldn't really figure out why and it seemed completely random (note that the phone's screen is off most of the time and everything is running in the background.), so I made a testscript which is what the question should focus on for simplicity:
#!/bin/sh
while : ; do
    echo &quot;$(date +'%Y-%m-%d %H:%M:%S')&quot;
    sleep 30
done

That's it. Started via nohup bash script.sh &amp; using SSHD. The script does nothing but print the current datetime and thanks to nohup writes it to a file. I left this running for a while and then wrote another script to check on the results and print the amount of seconds whenever it's above 30. Result:
134
127
115
127
88
113
116
99
110
116
54
44
70
75
62
82
94
68
429
62
81
126
144
39
467
71
62

This is from the output of a script that ran for only 4:20 hours, so quite a lot of times where execution must have been delayed, the sleep was longer than 30 seconds, or whatever is going on....
Can someone explain this? And is there a solution to this?
I suspect this might have something to do with memory or power management pausing the script but really it shouldn't happen and I would like my script to run in the background and to sleep for exactly 30 seconds and not be paused or delayed. In this testrun, the highest was 467 seconds, but the highest I've seen with the main script so far was a little over 20 minutes. This is rare, but 5-10 minutes of a delay happens a few times a day.
Android turns off some of CPUs and/or don't let apps use them when it's dozing. It's achieved through Linux kernel's Control Groups. One of the cgroups is cpuset that controls which CPU is assigned to which processes. Android creates multiple descendant cgroups in cpuset e.g. background, foreground, system-background, top-apps etc.

Apps are normally in background category which can use least no. of CPUs - usually one or two. Core native services like vold, zygote (and system_server), telephony services, and apps which run a foreground service (e.g. notification) or those exempted from Battery Optimization or those having privileges like allow-in-power-save are put in foreground group which can use CPUs even when device is in sleep mode.

So you need to add the script to foreground cgroup in order to keep it alive. From within script:

~# echo -n $$ &gt;/dev/cpuset/foreground/tasks


Going even more aggressive, you can hold a wake lock so that device doesn't suspend:

~# echo -n my_script &gt;/sys/power/wake_lock


Don't forget to release it (echo -n my_script &gt;/sys/power/wake_unlock) after stopping the script.

Please note that both of these measures can adversely affect your battery performance, particularly the latter. Android's warning:


  Creating and holding wake locks can have a dramatic impact on the host device's battery life