web-dev-qa-db-fra.com

Script Bash pour dormir à une température de CPU donnée ~ mise à jour pour 16.04

Ceci est une version radicalement mise à jour de la question. Je dois le mettre à jour car cette question est signalé comme un doublon de celui-ci, alors que cela n’a plus de réponse valable.


  • Version initiale de cette question, qui comportait l'étiquette 11.04:

Je suis nouveau dans les scripts et Linux, mon ordinateur est parfois trop chaud et je veux créer un script pour détecter temp1 et s'il dépasse 65 ° C, il doit le mettre en veille. J'ai du mal à comparer les valeurs dans le script, je n'arrive pas à définir correctement les chiffres, est-ce que quelqu'un pourrait le réparer, s'il vous plaît? Voici mon coup de poignard pour l'instant

#!/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

Ce qui précède a obtenu ne réponse avec un script qui, selon les commentaires, a été mis à jour pour fonctionner en 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

Comme indiqué dans la question liée, , le script ci-dessus ne fonctionne pas dans 16.04.

Cette question a obtenu ne réponse avec une version simpliste du script:

 #!/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

Mais pendant qu’il fait le travail (le système se met en veille à une température supérieure à 75), il faut plus de puissance de calcul que prévu et augmente la température jusqu’à 10 degrés celsius; c'est plus utile, plus rafraîchissant quand on ne tourne pas!

Je ne sais pas si le problème vient du script initial 11.04 ou du dernier changement, mais il faut une nouvelle réponse pour 16.04.

5
kenn

J'ai réussi à faire mon propre script.

#!/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

Pour 16.04 (aussi ici ):

#!/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
9
kenn

Introduction

Afin de faciliter à la fois les utilisateurs de commutateurs pré-système et post-système, j'ai écrit un script qui prend la méthode de suspension appropriée en fonction du numéro de version de votre système d'exploitation. En gros, il fait la même chose que le script mis à jour par OP, sauf qu'il force à suspendre malgré les inhibiteurs avec le drapeau -i. De nombreuses considérations et améliorations peuvent être apportées au script, mais pour le moment, cette version effectue 90% du travail.

Je l'ai testé brièvement sur 16.04 LTS, fonctionne parfaitement bien. À l'avenir, je pourrais réécrire ceci dans Python simplement parce que je le peux ou à la demande de l'utilisateur.

Source du script

#!/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 "$@"

Approche alternative

Il y a quelque temps, j'ai trouvé l'utilitaire pm-suspend, provenant du package pm-utils. Ce programme fonctionne quelle que soit la version du système d'exploitation. Le petit inconvénient est qu'il nécessite un accès root, mais il est facile de contourner ce désagrément.

Ce que je ferais personnellement est la suivante:

  1. Sudo apt-get install pm-utils
  2. Sudo visudo et ajoutez yourusername ALL = NOPASSWD: /usr/sbin/pm-suspend à la fin du fichier.
  3. éditez votre script pour appeler Sudo pm-suspend au lieu de la commande dbus.

Suspendre une machine Ubuntu en général

Vous avez demandé que les réponses s'appuient sur des sources crédibles. Ask Ubuntu a en fait un article canonique sur la suspension de la ligne de commande: Comment puis-je suspendre/mettre en veille de la ligne de commande? façons de peler un chat là-bas. Certains fonctionnent mieux que d'autres. Dans ma réponse, j’ai fourni l’approche dbus et systemctl, dans la mesure où ceux-ci fonctionnent également avec le verrouillage d’écran. Si vous écrivez sur /sys/class/power/state, l'écran ne sera pas verrouillé, bien qu'il soit possible de contourner cela avec un peu de magie de script. Pour le moment, je pense que la meilleure approche consiste simplement à déterminer la version du système d'exploitation et à sélectionner la méthode appropriée comme dans mon script, ou à utiliser pm-suspend alternative.

3
Sergiy Kolodyazhnyy

Sur mon système, chaque fois que vous exécutez sensors, le streaming vidéo est un bégaiement. Si cela se produisait toutes les 10 secondes ou si le script proposé était souvent exécuté, cela me rendrait fou. Une meilleure solution de suspension consisterait à utiliser Intel thermald et Powerclamp pour ralentir le processeur afin de réduire la chaleur. J'ai écrit cette réponse pour une autre question ( Arrêtez le processeur de surchauffer ) et je copie ici pour plus de commodité.

De plus, le script ci-dessus s'appuie sur temp1 qui est souvent corrompu sur Ubuntu 16.04 et seul temp3 est fiable à 100% et ne s'affiche pas sur sensors. c'est à dire:

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

et de sensors:

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

Cela se produit après une suspension/reprise. La température RÉELLE est de + 58,0 ° C, mais est faussement signalée comme étant de + 27,8 ° C après la reprise. Ainsi, la protection thermique ne fonctionnera qu'une seule fois et ne fonctionnera plus jusqu'au redémarrage. Ainsi, le système atteindrait un niveau critique (+ 106,0 ° C), point auquel une mise hors tension matérielle est effectuée et les données peuvent être corrompues.

Voici donc la solution que je recommande pour éviter la surchauffe et l’utilisation du processeur au lieu de l’interrompre complètement.

Ralentissez le processeur pour réduire la chaleur

Cela fonctionne pour Ubuntu 16.04+ avec Intel Sandy Bridge et les processeurs plus récents.

From ( wiki.debian.org -thermald ) correspond à l'écriture de Debian (utilisée par Ubuntu) sur (=)) , un démon Linux pour refroidir les tablettes et les ordinateurs portables. Une fois que la température du système atteint un certain seuil, le démon Linux active diverses méthodes de refroidissement pour refroidir le système.

Le daemon thermique Linux (thermald) surveille et contrôle la température dans les ordinateurs portables, les tablettes PC dotées du dernier Intel Sandy Bridge et des dernières versions de processeurs Intel. Une fois que la température du système atteint un certain seuil, le démon Linux active diverses méthodes de refroidissement pour tenter de refroidir le système.

Il fonctionne dans deux modes:

Mode de configuration zéro

  • Pour la plupart des utilisateurs, cela devrait suffire à maîtriser la température du processeur du système. Ceci utilise DTS capteur de température et utilise le pilote d’état P, le pilote de pince d’alimentation, le contrôle Limite de puissance moyenne en cours et cpufreq comme méthodes de refroidissement.

Mode de configuration défini par l'utilisateur

  • Cela permet la configuration de style ACPI dans un fichier de configuration XML thermique. Cela peut être utilisé pour corriger la configuration ACPI buggy ou peaufiner en ajoutant plus de capteurs et de dispositifs de refroidissement. Il s'agit d'une première étape dans la mise en œuvre d'un contrôle thermique en boucle fermée en mode utilisateur et peut être amélioré en fonction des commentaires et des suggestions de la communauté.

Comment installer

apt-get install thermald

Intel Powerclamp

Le pilote Intel Powerclamp est défini ici ( kernel.org - Intel Power Clamp.txt ) et fait partie de thermald décrit ci-dessus. Un devis direct pour Powerclamp à partir du lien:

Prenons le cas où la consommation électrique d’un système doit être réduite au moment de l’exécution, en raison du bilan énergétique, des contraintes thermiques ou du niveau de bruit, et où le refroidissement actif n’est pas préféré. La réduction de puissance passive gérée par logiciel doit être effectuée pour empêcher les actions matérielles conçues pour des scénarios catastrophiques.

Actuellement, les états P, les états T (modulation d'horloge) et le décalage de la CPU sont utilisés pour la régulation de la CPU.

Sur les processeurs Intel, les états C permettent de réduire efficacement la consommation d'énergie, mais jusqu'à présent, ils ne sont utilisés que de manière opportuniste, en fonction de la charge de travail. Avec le développement du pilote intel_powerclamp, la méthode de synchronisation de l'injection inactive dans tous les threads de processeur en ligne a été introduite. L’objectif est d’obtenir la résidence forcée et contrôlable dans l’État C.

Les tests/analyses ont été réalisés dans les domaines de la puissance, des performances, de l'évolutivité et de l'expérience utilisateur. Dans de nombreux cas, l’avantage évident est de mettre le CPU hors ligne ou de moduler son horloge.


Comment savez-vous que Powerclamp fonctionne?

Powerclamp pourrait ne se manifester qu'une fois par an lorsque les ventilations de votre ventilateur reçoivent trop de poussière et de peluches. Alors, comment savez-vous qu'il fonctionne en arrière-plan? Utilisation:

lsmod | grep intel

Et vous devriez voir une liste semblable à ceci:

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

Si vous voyez intel_rapl et intel_powerclamp, vous savez que cela fonctionne et que vous attendez simplement le temps de dépasser 85 ° C.


Powerclamp en action affiché par Conky

Voici une capture d’écran lorsque Powerclamp injecte des cycles de sommeil:

Kidie Injection

Normalement, sur ce système, la vitesse d'horloge du processeur est comprise entre 2 400 et 3 400 MHz lorsque vous regardez une vidéo au format HTML5 et que 10 onglets Chrome s'ouvrent. En règle générale, l'utilisation du processeur est d'environ 9% à 12% sur 8 processeurs. Lorsque les choses deviennent trop chaudes ( 86C ) , Powerclamp se déclenche et ceci se produit:

  • La vitesse du processeur est réduite à 1200 Mhz.
  • L'utilisation du processeur atteint 80%. Ceci est trompeur car les 70% supplémentaires représentent le temps de sommeil.
  • Les 9 principaux processus du processeur sont généralement 5 ou 6 processus Chrome plus Xorg, Conky, Pulse Audio et un kworker occasionnel. Cependant, maintenant, 8 des 10 meilleurs sont les processus kidle_inject/x x est compris entre 0 et 7. Pour les 8 premiers CPU.

Le pilote Powerclamp s'exécute jusqu'à ce que la température baisse à nouveau sous la barre des 85 ° C. Pendant que le pilote est en cours d'exécution, il est possible que vous ayez une pause d'une fraction de seconde dans vos vidéos et éventuellement un décalage du clavier et de la souris d'une seconde.


Désactiver Intel Turbo Boost

De retour dans les "vieux temps froids" d'Ubuntu 14.04, Intel Turbo Boost était en panne, donc la vitesse de mon processeur fluctuait entre 1200 Mhz et 2400 Mhz. Après la mise à niveau vers Ubuntu 16.04, il passerait à 3400 MHz (3,4 Ghz) car Turbo Boost fonctionnait enfin. Mais il a également augmenté la chaleur.

Pour désactiver Intel Turbo Boost, utilisez:

echo "1" | Sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
2
WinEunuuchs2Unix

J'ai radicalement modifié la question ci-dessus afin de demander des mises à jour pour le 16.04 et ma réponse ci-dessous n'est donc qu'une mise à jour du la réponse initiale de Kenn , sur laquelle j'ai posté ne question dupliquée et est aussi un réponse en dessous de cela.

Comme l'erreur de 16.04 était Error org.freedesktop.DBus.Error.UnknownMethod: No such method 'Suspend', après le commentaire fait par Nick Sillito sous ma question dupliquée liant à this répondre, je ont modifié le script en remplaçant toute cette partie:

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

avec

    systemctl suspend

Comme indiqué dans le commentaire de wjandreea sous la question dupliquée : sleep 10 ou une valeur similaire ne doit pas être supprimée (comme je l'avais initialement); sans cette ligne, le script modifié utilisera plus de puissance car au lieu de s'exécuter toutes les 10 secondes, il sera aussi rapide que possible - jusqu'à plusieurs dizaines de fois par seconde.

À ce stade, le système se met en veille en dépassant le niveau défini dans la ligne.

max="+75.0"

Comme je veux une valeur plus élevée, 82, le script que j'utilise est le suivant:

#!/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
0
user47206