Keeping Mac OSX up and sleepless while task / app is running

10

2

I want to leave rsync working over wifi for hours turned on AC power. But when I do so the Mac breaks the connection after some time.

On Energy Settings pane it's configured to "Computer Never Sleep", "Put hard disk to sleep when possible" and "Wake for network access".

Plus it'd be good if the mac actually goes to sleep once the task is done.

I realize a very similar question have been asked before and that there is pmset and insomniaX, but I don't want the machine to be sleepless. And I don't want to keep installing more and more extensions, nor have to tweak through pmset every time.

I want it to natively behave as expected - stay awake while I leave it running a task, and then go to sleep "when possible". This time is due to rsync, but next time could be something else.

Am I expecting too much as usual? Can I fix it? Is it even broken?

cregox

Posted 2010-02-22T15:34:27.067

Reputation: 5 119

Answers

10

Caffeinate

For example:

caffeinate -i rsync -avz someuser@somehost:somefolder /some/local/folder

From the man page:

EXAMPLE
     caffeinate -i make
        caffeinate forks a process, execs "make" in it, and holds an
        assertion that prevents idle sleep as long as that process
        is running.

It can also be used for situations like "don't let the display sleep while I'm watching this movie":

caffeinate -d # in effect until you hit Ctrl+C

... or "stay awake for the next 10,000 seconds":

caffeinate -t 10000

See man caffeinate for details.

Nathan Long

Posted 2010-02-22T15:34:27.067

Reputation: 20 371

2This is insanely awesome! Is this default on any OSX? Since which version? (I couldn't quickly find info about this) – cregox – 2014-09-04T15:49:30.300

@Cawas - according to this article, it started shipping with Mountain Lion: http://www.cnet.com/news/caffeinate-mountain-lion-to-prevent-it-from-sleeping/ I found out about it from man pmset, where the noidle option is listed as deprecated.

– Nathan Long – 2014-09-04T18:02:10.760

4

Jiggler can be set to only "jiggle" the mouse when it's running. This will prevent the screen and the computer from sleeping. This will not work on a laptop with the lid shut. For that you'd need InsomniaX or another kext based application.

enter image description here

Josh K

Posted 2010-02-22T15:34:27.067

Reputation: 11 754

No lid shut, that's fine. I don't want overheat. – cregox – 2010-02-22T15:52:10.853

Handy little application, indeed. – ayaz – 2010-02-22T16:29:09.947

Well, while I don't need it again, this actually solved my problem, and it seems like a nice solution. I guess I should have accepted it way before. – cregox – 2010-03-09T01:16:00.283

2

Another alternative is Caffeine. It's an app - not an extension - which keeps the machine "active" for a specified period of time, after which the machine can do whatever it would normally do: go blank, run screensaver, sleep, etc. That is, it won't put your machine to sleep, but will let it. It seems functionally equivalent to setting the energy saver settings to "never" for the period you ask for, and restoring them afterward.

enter image description here

JRobert

Posted 2010-02-22T15:34:27.067

Reputation: 6 128

But you still have to start and stop the app. You can't set it and forget. – Josh K – 2010-02-23T00:26:56.337

1

You might consider making a Stay-Open Applescript Application that sets/resets the sleep timer based on the existence of a running process. Creating a launchd plist is also a viable solution, however I'm still shaky on the syntax. The "pmset force sleep X" command doesn't require root access, but the settings are reset on reboot.

Since your situation sounds like I won't be able to anticipate your every need, I'll sketch something out for you.

property LoopTime: 5 --measured in seconds
property normalSleepTimeout: 30 --measured in minutes
property processName: "rsync"  --the name of the process you're trying to find

on run
   do shell script "pmset force sleep 0"  --disables sleep
   idle()
end

on idle
   if not appIsRunning() then 
      do shell script ("pmset force sleep " & normalSleepTimeout as string) -- sets sleep to desired idle timeout
      quit
   end
   return 
end

on appIsRunning()
   --Here's where you need to do the test that an app is running.  True needs to mean "the app is running".  Store the value to "result" or change the below return statement.

   return result
end

For things like rsync and background processes, you'll need to get more clever and poll other functions like $ top.

set result to False
if 0 < (count of (do shell script ("top -l 1 | grep" & processName as string))) then
   set result to True
end

Notice that in the above case, searching for just "rsync" will return a false positive if rsyncd is running because both "rsync" and "rsyncd" match. You may have to get more tricky if this doesn't work for you.

If the application were a Windowed process, I'd use the following to determine what's running:

tell application "System Events" to set RunningAppNames to name of processes

Or for bundle identifiers (more precise)

tell application "System Events" to set RunningBundles to bundle identifier of processes

Tell me more about your scenario and I'll try to write something more exact and with a more flexible user interface.

dotHTM

Posted 2010-02-22T15:34:27.067

Reputation: 1 534

dam, I'll look at all you said here another time, but thanks for going through all this trouble! I'm not really considering writing scripts for now, though. :) – cregox – 2010-02-23T19:34:14.547

Thanks for bringing my answer back up to a non-negative value. I live by scripting. I'm terrible with BASH, but I absolutely love AppleScript and running Terminal commands from it. – dotHTM – 2010-03-01T05:41:38.803