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="idle") but it still didn't work. According to the man page, the default is
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.