4

Recently I ran a long-running script that I started from a Terminal window in Ubuntu 16.04 x64. When I walked away from the system, it eventually suspended automatically after the 20 minutes that I had it configured to in the System Settings window, which had the effect of pausing the script. When I returned to the system, I realized that several hours of progress on the execution of my script was lost because the system had suspended.

One workaround is to manually select Don't suspend in the Power settings window chosen from System Settings. This method to prevent suspend is unsatisfactory (1) because I often forget to do it, and (2) because it makes me subservient to my system.

Perhaps there's a slicker but still manual way of doing this with some kind of prefix command, which I'll call nosuspend for now, with this usage: nosuspend python myscript.py arg1 arg2. My main gripe with this mythical command is that it still requires that I remember to use it, and, since it's unreasonable to prefix all terminal commands, one has to predict whether a script will take 1 minute or 1 hour to run, and this prediction may be incorrect, leading again to time loss and frustration.

Ideally, the solution would prevent suspend until all commands run from a Terminal window complete. At some level, I realize this is impossible, as a bash process within the Terminal window may well have a subprocess that we may not want to prevent sleep, e.g., sudo su executed in a Terminal window is still running even though we may not be currently using it, and is thus idle, but we still want the system to suspend automatically after 20 minutes, say. So, there is a problem of defining criteria for suspend.

I must note that the Python script in question had only sporadic disk, network, and almost no CPU work, as it had repeated Python time.sleep() calls of up to less than a minute per call. Therefore, I'm not particularly looking for methods that merely detect a "fairly" quiescent state in disk, network, or CPU. Perhaps there's a way to detect if a command that is a subprocess of Terminal has made any progress at all during an interval (hopefully the same interval configured in Power above). Hopefully that would distinguish my script from the above idle sudo su counter-example.

Update 1 (14-September-2016):

As recommended by Adrine Correya below, I tried systemd-inhibit, which sounds like the imagined nosuspend above, but it didn't work. Here's what I did. First I created a Python test script called "long-job.py":

#!/usr/bin/python3
import time
print("starting")
for i in range(10):
  time.sleep(10)
  print("epoch", i)
print("all done")

Then I made it executable using chmod +x long-job.py. To speed up testing, I set org>gnome>settings-daemon>plugins>power>sleep-inactive-ac-timeout to 20 (seconds) using dconf-editor (installed via Ubuntu Software). I then ran the script, without root/sudo, using systemd-inhibit ./long-job.py, but the system still went to sleep before the job was finished (it should take around 100 seconds to run, but sleep happened after 20 seconds). I also tried a few of the options (--what="sleep" and --what="idle") but it still didn't work. According to the man page, the default is --what="idle:sleep:shutdown".

Update 2 (14-September-2016):

On Mac OS X, it seems that caffeinate actually implements the nosuspend idea above; see https://superuser.com/questions/99247/stop-a-mac-from-sleeping-while-a-bash-script-is-running-then-allow-it-to-sleep. Again, it would be nice to have this automated, so we don't have to guess which jobs might be long-running. Also, a Ubuntu version is needed.

2 Answers2

6

I'm not sure, but have you tried systemd-inhibit? It works on Linux boxes running on systemd (Ubuntu 16.04 being on of them, AFAIK).

Look at the manpages, man systemd-inhibit for help.

  • Note that at least with MATE desktop on Ubuntu 18.04 the MATE ignores systemd-inhibit if user selects suspend from the UI. I've found that inhibit does work correctly if I use both: systemd-inhibit --what "sleep:handle-suspend-key" mate-session-inhibit --inhibit suspend <COMMAND TO RUN> – Mikko Rantalainen Jun 04 '21 at 08:10
1

I wrote a program keepawake.py that can monitor cpu activity, network traffic, and user activity (mouse/keyboard). This may solve your problem. I posted it here on AskUbuntu...

Is there any way to make Ubuntu not to suspend while a download in progress?

If your long running script causes any network traffic or triggers a certain percentage of cpu activity then the program above can solve your problem.

DanglingPointer
  • 1,123
  • 1
  • 13
  • 23