Bash脚本在给定的CPU温度下睡眠〜更新为16.04

这是问题的根本更新版本。 我必须更新这个,因为这个问题被标记为此问题的副本,而这已经没有有效答案了。


  • 此问题的初始版本,其中包含11.04标记:

我是脚本和linux的新手,我的comp有时太热了,我想制作一个脚本来检测temp1,如果它超过65 C,它必须让它进入睡眠状态。 我在比较脚本中的值时有困难,我无法正确定义数字,请问有人会修复吗? 到目前为止,这是我的努力

#!/bin/bash max=65 val=$ sensors | grep '^temp1:' | sed -e 's/.*: \+\([+-][0-9.]\+\)°C.*$/0\1/' while true; do if [[ "$val" > "$max" ]]; then sudo /etc/acpi/sleep.sh force sleep 1 else sleep 10 fi clear sensors done 

上面的答案是一个脚本,根据评论在某些时候更新到14.04工作

  #!/bin/bash while true; do val=$(sensors | awk '/temp1/ {print $2}') max="+75.0" if [[ "$val" > "$max" ]]; then dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend fi sleep 10 clear sensors done exit 0 

如链接问题所示, 上述脚本在16.04中不起作用。

这个问题通过简单修改的​​脚本版本得到了答案 :

  #!/bin/bash while true; do val=$(sensors | awk '/temp1/ {print $2}') max="+75.0" if [[ "$val" > "$max" ]]; then systemctl suspend fi clear sensors done exit 0 

但是当它完成工作时(系统在高于75时进入睡眠状态),它需要比预期更多的CPU功率,并在运行高达10摄氏度时将温度提高; 这更有用,不运行时更冷却!

我不知道问题是在初始11.04脚本还是最后一次更改,但这需要16.04的新答案。

我设法制作了自己的剧本。

 #!/bin/bash while true; do val=$(sensors | awk '/temp1/ {print $2}') max="+75.0" if [[ "$val" > "$max" ]]; then dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend fi sleep 10 clear sensors done exit 0 

对于16.04(也在这里 ):

 #!/bin/bash while true; do val=$(sensors | awk '/temp1/ {print $2}') max="+75.0" if [[ "$val" > "$max" ]]; then systemctl suspend fi sleep 10 clear sensors done exit 0 

介绍

为了方便系统前系统和后系统切换用户,我编写了一个脚本,根据你的操作系统版本号采取适当的挂起方法。 本质上它与OP的更新脚本做的事情相同,除非它强制暂停,尽管有-i标志的抑制器。 可以对脚本进行多种考虑和改进,但是现在这个版本完成了90%的工作。

我在16.04 LTS上进行了短暂测试,效果非常好。 将来我可能只是因为我可以或根据用户请求在Python中重写它。

脚本来源

 #!/usr/bin/env bash suspend_system(){ os_version=$(awk -F'["=]' '/VERSION_ID/{print substr($3,1,2)}' /etc/os-release) if [ $os_version -ge 15 ] then systemctl suspend -i # Alternative way is to call login manager method via dbus # qdbus --system org.freedesktop.login1 /org/freedesktop/login1 \ # org.freedesktop.login1.Manager.Suspend True else dbus-send --system --print-reply --dest="org.freedesktop.UPower"\ /org/freedesktop/UPower org.freedesktop.UPower.Suspend fi } is_critical_temp(){ local temp=$(sensors | awk '/temp1/ {print substr($2,2,2)}') if [ $temp -gt 75 ] then return 0 else return 1 fi } main(){ while true do if is_critical_temp then # optional dialog if running from GUI, not necessary if running form /etc/rc.local #zenity --info --text "Reached critical temperature. Suspending in 10 seconds" & sleep 10 suspend_system fi sleep 3 done } main "$@" 

替代方法

前一阵子,我从pm-utils包中找到了pm-suspend实用程序。 无论操作系统版本如何,此程序都可以使 缺点是它需要root访问权限,但很容易避免这种不便。

我个人会做的是以下内容:

  1. sudo apt-get install pm-utils
  2. sudo visudo并在文件末尾添加你的yourusername ALL = NOPASSWD: /usr/sbin/pm-suspend
  3. 编辑脚本以调用sudo pm-suspend而不是dbus命令。

暂停一台Ubuntu机器

你已经要求答案依据可靠的消息来源。 事实上,Ask Ubuntu确实有关于从命令行暂停的规范post: 如何从命令行暂停/hibernate? 根据您希望脚本拥有的权限的方法和级别,有多种方法可以在那里为猫设置皮肤。 有些比其他人好。 在我的回答中,我提供了dbus和systemctl方法,因为这些方法也适用于屏幕锁定。 如果您写入/sys/class/power/state ,它将不会锁定屏幕,尽管可以通过一些脚本魔术解决这个问题。 现在,我认为,更好的方法是简单地确定操作系统版本并选择适当的方法,如我的脚本,或使用pm-suspend替代。

在我的系统上,每次运行sensors ,video流都会出现断断续续的情况。 每10秒钟发生这种情况,或者经常建议的脚本运行会让我蝙蝠疯狂。 一个更好的暂停解决方案是使用英特尔的thermaldPowerclamp减速CPU以减少热量。 我已经为另一个问题( 停止cpu过热 )写了这个答案,为了方便,我在这里复制。

另外,上面的脚本依赖于temp1 ,这在我的Ubuntu 16.04上经常被破坏,只有temp3是100%可靠的,不会出现在sensors 。 即:

 $ cat /sys/class/thermal/thermal_zone*/temp 27800 29800 58000 

sensors

 acpitz-virtual-0 Adapter: Virtual device temp1: +27.8°C (crit = +106.0°C) temp2: +29.8°C (crit = +106.0°C) 

暂停/恢复后会发生这种情况。 实际温度为+ 58.0°C,但在恢复后错误地报告为+ 27.8°C。 因此,热保护只能暂停一次,并且在重新启动之前不会再次工作。 因此系统将达到临界值(+ 106.0°C),此时执行硬关机并且数据可能被破坏。

所以这是我建议的解决方案,以防止过热和利用CPU减速而不是彻底的系统暂停。

减慢CPU以减少热量

这适用于Ubuntu 16.04+和Intel Sandy Bridge以及更新的处理器。

来自( wiki.debian.org -thermald )的Debian(由Ubuntu使用)写了一篇关于thermald的文章 ,这是一款用于冷却平板电脑和笔记本电脑的Linux守护进程。 一旦系统温度达到某个阈值,Linux守护程序将激活各种冷却方法以冷却系统。

Linux热备份监控器(thermald)监控和控制笔记本电脑,平板电脑的温度,配备最新的英特尔沙桥和最新的英特尔CPU版本。 一旦系统温度达到某个阈值,Linux守护程序将激活各种冷却方法以尝试冷却系统。

它以两种模式运行:

零配置模式

  • 对于大多数用户来说,这应该足以使系统的CPU温度受到控制。 这使用DTS温度传感器,并使用Intel P状态驱动器,电源钳驱动器,运行平均功率限制控制和cpufreq作为冷却方法。

用户定义的配置模式

  • 这允许在热XML配置文件中配置ACPI样式。 这可以通过添加更多传感器和冷却设备来修复错误的ACPI配置或微调。 这是在用户模式下实现闭环热控制的第一步,可以根据社区反馈和建议进行增强。

如何安装

 apt-get install thermald 

英特尔Powerclamp

英特尔的Powerclamp驱动程序在此定义( kernel.org – Intel Power Clamp.txt ),是上述thermald的一部分。 从链接直接引用Powerclamp

考虑由于功率预算,热约束或噪声水平以及不优选主动冷却而必须在运行时降低系统功耗的情况。 必须执行软件管理的被动功率降低,以防止针对灾难性场景设计的硬件操作。

目前,P状态,T状态(时钟调制)和CPU离线用于CPU限制。

在Intel CPU上,C状态提供有效的功率降低,但到目前为止,它们仅基于工作负载在机会上使用。 随着intel_powerclamp驱动程序的发展,引入了跨所有在线CPU线程同步空闲注入的方法。 目标是实现强制和可控的C状态驻留。

在功耗,性能,可扩展性和用户体验方面进行了测试/分析。 在许多情况下,显示优于将CPU脱机或调制CPU时钟的优点。


你怎么知道Powerclamp正在运行?

Powerclamp可能每年只会出现一次,当你的风扇通风口有太多灰尘和皮屑时。 那么你怎么知道它实际上是在后台运行的呢? 使用:

 lsmod | grep intel 

你应该看到一个类似这样的列表:

 btintel 16384 1 btusb bluetooth 520192 29 bnep,btbcm,btrtl,btusb,rfcomm,btintel intel_rapl 20480 0 intel_powerclamp 16384 0 (.... more intel drivers ....) snd 81920 18 snd_hwdep,snd_timer,snd_hda_codec_hdmi,snd_hda_codec_idt,snd_pcm,snd_seq,snd_rawmidi,snd_hda_codec_generic,snd_hda_codec,snd_hda_intel,snd_seq_device 

如果你看到intel_raplintel_powerclamp你知道它正在工作,只是等待温度超过85C。


Conky展示的Powerclamp在行动中

这是Powerclamp注入睡眠周期时的屏幕截图:

Kidie注射液

通常在此系统上,当观看HTML5video和打开10个Chrome标签时,CPU时钟速度为2400 Mhz至3400 Mhz。 通常,8个CPU的CPU利用率约为9%到12%。 当事情变得太热( 86CPowerclamp开始发生这种情况:

  • CPU速度降至1200 Mhz。
  • CPU利用率高达80%。 这是误导,因为额外的70%是睡眠时间。
  • 前9个CPU流程通常是5或6个Chrome进程加上Xorg,Conky,Pulse Audio和偶尔的kworker。 但是现在排名前10的中有8个是kidle_inject / x进程,其中x是0到7.对于前8个CPU。

Powerclamp驱动程序运行直到温度再次降至85℃以下。 当驱动程序运行时,您可能在video中分离了第二个暂停,并可能分割出第二个键盘和鼠标滞后。


禁用Intel Turbo Boost

回到Ubuntu 14.04的“酷时光”,英特尔Turbo Boost被破坏,因此我的处理器速度在1200 Mhz和2400 Mhz之间波动。 升级到Ubuntu 16.04后,它将达到3400 Mhz(3.4 Ghz),因为Turbo Boost终于正常工作。 但它也提高了热度。

要禁用Intel Turbo Boost,请使用:

 echo "1" | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo 

我已经彻底编辑了上面的问题,以便要求16.04的更新,因此我的答案只是对Kenn的初步答案的更新,我在其上发布了一个重复的问题 ,也是一个答案 。

因为16.04中的Error org.freedesktop.DBus.Error.UnknownMethod: No such method 'Suspend'Error org.freedesktop.DBus.Error.UnknownMethod: No such method 'Suspend' ,在Nick Sillito根据我的重复问题链接到这个答案的评论之后,我通过替换整个部分修改了脚本:

  dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend 

  systemctl suspend 

正如wjandreea在重复问题下所作的评论所示: sleep 10或类似的值不应被删除(正如我最初所做的那样); 没有那条线,修改后的脚本将使用更多的功率,因为​​它不会每10秒运行一次,它将尽可能快 – 每秒超过几十次。

此时,系统在超过线路中设置的水平时进入睡眠状态

 max="+75.0" 

因为我想要更高的值,82,我使用的脚本是:

 #!/bin/bash while true; do val=$(sensors | awk '/temp1/ {print $2}') max="+82.0" if [[ "$val" > "$max" ]]; then systemctl suspend fi sleep 10 clear sensors done exit 0