2

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 & 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 "$(date +'%Y-%m-%d %H:%M:%S')"
    sleep 30
done

That's it. Started via nohup bash script.sh & 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.

5

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 $$ >/dev/cpuset/foreground/tasks

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

~# echo -n my_script >/sys/power/wake_lock

Don't forget to release it (echo -n my_script >/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

| improve this answer | |
  • wow, my poor interim was always send input keyevent every 10 seconds. is that the same list used for battery safer in settings? – alecxs Feb 21 at 10:08
  • 2
    @alecxs it's partially yes. There are other factors too. Android's power management is complicated. After OEM's contribution it also becomes uncertain and frustrating. I've been thinking about explaining this topic in detail but I think that would become too much detailed. And I'm not aware of many OEM-specific things. – Irfan Latif Feb 21 at 11:08
  • 1
    +1: I learned something beyond simple wakelocks today. Very nice answer. – Grimoire Feb 26 at 23:13
  • 1
    @DeathMaskSalesman I'm honored. – Irfan Latif Feb 27 at 8:06
  • 1
    I wish I could upvote an answer twice. Been running smoothly since weeks now, saving me a lot of headaches. Thanks again, and after having it running like this for weeks now I can clearly say that the battery consumption is nearly the same. I don't notice worse performance at all (again using only the first trick). – confetti Mar 8 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.