一般情况下,macOS在休眠时会自动断开网络,从系统的设计角度来说这还算是比较合理,只是苹果的系统设计师大概不知道我们国内的网络有多烂,下载几个文件是不能按分钟计的,常常就是个把小时甚至几个小时,往往出现这种情况:当我喝完一杯咖啡过来看下载是否完成的时候,发现网络早就断了!
一般的解决方案是在【节能】中将【电脑进入睡眠】的滑动条拉到最右边的【永不】位置就能防止系统休眠,自然也就阻止了断网,但我感觉仅仅因为一个临时需要就更改系统设置仿佛有点小题大作,而且对我来说,阻止休眠只有在进行下载的时候才有这个需要,平时我还是希望能用比较环保的方式使用电脑。一句话,我的希望就是某个应用运行的时候不断网,其他的时候还是环保节能为好
一
当媒体播放器(如iTunes、mpv……)运行的时候,只要它在播放,就不会进入休眠,这个时候发生了什么呢?让我们来看一下:
pmset
是系统自带的电源管理设置程序,很明显在运行播放器之前,sleep
是正常工作的,时间一到就睡你没商量,当我把播放器打开,再次检查系统的电源管理时,发现sleep
被阻止了——sleep prevented by coreaudiod
,原来机关在这里,只要我们能找到一个临时阻止的方式,系统就不会休眠。
有这个方法吗?当然有,还在10.4版本的时候,苹果就带了一个叫caffeinate
的系统工具,而且这个程序使用非常简单,带一个-w
的开关,并接上需要守护的进程ID,就会阻止系统休眠,直到这个进程退出为止。
二
到这里思路很清楚了,大概就是两步:
- 获得需要监控的进程的ID
- 用caffeinate来守护这个进程,只要这个进程不退出,系统就不会休眠
既然是两步,那就写一个脚本来操作好了,我将脚本文件命名为prevent_sleep
,放在/usr/local/bin
中,内容如下:
#!/bin/sh
if [[ -n "$1" ]]; then
pid=$(ps rax | awk '{print $1, $5}' | grep -i "$1" | cut -d ' ' -f 1)
if [[ -n $pid ]]; then
caffeinate -s -w "$pid" &
echo "Systemp sleep prevented by $1"
else
echo "Sorry, the $1 could not be found."
fi
else
echo "Please enter the name of the program that you want to wait."
echo "Example:"
echo " prevent_sleep wget"
fi
脚本首选检查有没有参数(需要监控的程序名称),没有的话就提示信息;有的话,就在当前系统中查找这个进程的PID,并将PID传递给caffeinate
,然后caffeinate
就在后台默默运行,只要被监控的程序不退出,caffeinate
就不会退出。
三
最后,让我们来看看有没有效果:
如上图所示,开始系统是正常模式(10分钟之后休眠),然后执行prevent_sleep qq
,这个时候系统的电源模式就变成了sleep prevented by caffeinate
,只要QQ在运行,系统就不会进入休眠状态,在任何时候,只要退出QQ程序,系统就会恢复正常模式。
好了,我该去喝一杯咖啡了……