Как запускать или убивать задачи, когда температура ядра выше / ниже определенного значения?

Я хотел бы написать короткий скрипт, который запускается вручную один раз, а затем должен:

запускать команду, если все температуры ниже x ° C. приостанавливайте команду, если какая-либо температура поднимается выше y ° C. продолжайте команду, как только все температуры снова опустится ниже x ° C.

Конечно, это x°C < y°C.

Я могу получить значения температуры, например. через команду sensors:

$ sensors | grep °C
temp1:        +68.0°C  (crit = +95.0°C)
Core 0:       +68.0°C  (high = +80.0°C, crit = +90.0°C)
Core 2:       +67.0°C  (high = +80.0°C, crit = +90.0°C)

Сценарий должен быть завершен все время, например. через killall scriptname. Если это не сработает с вашим решением (например, потому что он зарегистрирует любые запланированные события для опроса температуры), мне нужна отдельная команда для его выхода.

Как я могу написать этот скрипт? [!d11 ]

1
задан 20 January 2016 в 04:00

6 ответов

Это может сработать:

#!/bin/bash

targettemp=90
started=1

COMMAND &

trap "kill COMMAND; exit" SIGINT SIGTERM

while true
do
  currenttemp=$(sensors -u | awk '/temp1_input/ {print $2; exit}' )
  compare=$(echo $currenttemp'>'$targettemp | bc -l)
  if [ "$compare" -eq 1 ] && [ "$started" -eq 1 ] 
  then
    started=0
    kill -STOP COMMAND
  fi
  if [ "$compare" -eq 0 ] && [ "$started" -eq 0 ]
  then
    started=1
    kill -CONT COMMAND
  fi
  sleep 1 & wait $!
done

Это приведет к появлению текущего «temp1» результата от датчиков, обрезает любые другие символы, которые ему не нужны, чтобы bash мог видеть это как число, затем сравните его с любой заданной вами температурой. Мои рассуждения по поводу добавления «NR + 1000», а затем grep 1001 состоят в том, что в sensors у вас могут быть два результата «temp1», как и я. Это своего рода kludge, но он работает.

Затем, когда вы хотите его убить, просто killall script.sh.

Линия sleep 1 заключается в том, чтобы избежать избыточного потребления ЦП из оживленного ожидания. Вы можете изменить это на любой sleep duration, который вам нравится, если вы хотите только опросить температуру так часто.

4
ответ дан 23 May 2018 в 14:11

Сценарий

#!/usr/bin/env python3
import subprocess
import time
import sys

low = int(sys.argv[1]); high = int(sys.argv[2]); command = sys.argv[3:]; proc = command[0]

def get_temps():
    data = subprocess.check_output("sensors").decode("utf-8").splitlines()
    return sum([[float(l.split(":")[1].split()[0].replace("+", "").replace("°C", "")) \
        for l in data if l.startswith(mark)]for mark in ["temp1", "Core"]], [])

def manage_start():
    try:
        pid = subprocess.check_output(["pgrep", proc]).decode("utf-8").strip()
        subprocess.Popen(["killall", "-s", "CONT", proc])
    except subprocess.CalledProcessError:
        subprocess.Popen(["/bin/bash", "-c", (" ").join(command)])

run = False

while True:
    time.sleep(1)
    if run == False:
        if all([n < low for n in get_temps()]):
            manage_start(); run = True  
    elif run == True:
        if not all([n < high for n in get_temps()]):
            subprocess.Popen(["killall", "-s", "STOP", proc]); run = False

Как использовать

Скопировать сценарий в пустой файл, сохранить его как temp_run.py Запустить его, лучше всего до запуска процесса (сценарий начнет процесс), с (впоследствии) low_temp, high_temp, process_name и возможные аргументы в качестве аргументов. Я тестировал его, например, с помощью:
python3 /path/to/temp_run.py 60 80 gedit /path/to/file.txt
(используя другой текстовый редактор для изменения номеров)

Как я его протестировал

Поскольку у меня нет разнообразия в реальной температуре, в скрипте я заменил функцию get_temps() функцией, считывая числа из текстового файла.

Таким образом, «подавая» сценарий с виртуальными температурами, он выполнял задание без ошибок: пауза выше «высокая» при работе, возобновляющаяся ниже «низкая» при паузе.

Как это сделать works

Когда скрипт запускается

, он проверяет, находятся ли все температуры ниже нижнего порога. Если это так, то он либо запускает процесс, либо возобновляет его, если он уже запущен, и устанавливает переменную: run = True. В результате следующий тест заключается в том, что все временные параметры ниже самого высокого порога, если нет, процесс приостанавливается , скрипт устанавливает: run = False, делая следующий тест, если все темпы ниже нижнего и т. д. ...

Как убить его

Сценарий может быть убит :

kill "$(pgrep -f temp_run.py)"
2
ответ дан 23 May 2018 в 14:11
  • 1
    Как я уже сказал, мне нужна версия, которая принимает аргументы. В вашей строке исключаются исключения из строки pgrep. И вы, вероятно, должны использовать killall commandname вместо kill pid, потому что моя команда порождает 3 других экземпляра себя с разными PID. См. Мой комментарий ниже ответа kos , пожалуйста. – Byte Commander 20 January 2016 в 12:43
  • 2
    @ByteCommander Насколько я вижу (и насколько я могу проверить), новая версия выше должна работать. Теперь скрипт принимает аргументы и приостанавливает / возобновляет все экземпляры имени процесса. – Jacob Vlijm 20 January 2016 в 13:24

Это может сработать:

#!/bin/bash

targettemp=90
started=1

COMMAND &

trap "kill COMMAND; exit" SIGINT SIGTERM

while true
do
  currenttemp=$(sensors -u | awk '/temp1_input/ {print $2; exit}' )
  compare=$(echo $currenttemp'>'$targettemp | bc -l)
  if [ "$compare" -eq 1 ] && [ "$started" -eq 1 ] 
  then
    started=0
    kill -STOP COMMAND
  fi
  if [ "$compare" -eq 0 ] && [ "$started" -eq 0 ]
  then
    started=1
    kill -CONT COMMAND
  fi
  sleep 1 & wait $!
done

Это приведет к появлению текущего «temp1» результата от датчиков, обрезает любые другие символы, которые ему не нужны, чтобы bash мог видеть это как число, затем сравните его с любой заданной вами температурой. Мои рассуждения по поводу добавления «NR + 1000», а затем grep 1001 состоят в том, что в sensors у вас могут быть два результата «temp1», как и я. Это своего рода kludge, но он работает.

Затем, когда вы хотите его убить, просто killall script.sh.

Линия sleep 1 заключается в том, чтобы избежать избыточного потребления ЦП из оживленного ожидания. Вы можете изменить это на любой sleep duration, который вам нравится, если вы хотите только опросить температуру так часто.

4
ответ дан 23 May 2018 в 14:11

Это может сработать:

#!/bin/bash

targettemp=90
started=1

COMMAND &

trap "kill COMMAND; exit" SIGINT SIGTERM

while true
do
  currenttemp=$(sensors -u | awk '/temp1_input/ {print $2; exit}' )
  compare=$(echo $currenttemp'>'$targettemp | bc -l)
  if [ "$compare" -eq 1 ] && [ "$started" -eq 1 ] 
  then
    started=0
    kill -STOP COMMAND
  fi
  if [ "$compare" -eq 0 ] && [ "$started" -eq 0 ]
  then
    started=1
    kill -CONT COMMAND
  fi
  sleep 1 & wait $!
done

Это приведет к появлению текущего «temp1» результата от датчиков, обрезает любые другие символы, которые ему не нужны, чтобы bash мог видеть это как число, затем сравните его с любой заданной вами температурой. Мои рассуждения по поводу добавления «NR + 1000», а затем grep 1001 состоят в том, что в sensors у вас могут быть два результата «temp1», как и я. Это своего рода kludge, но он работает.

Затем, когда вы хотите его убить, просто killall script.sh.

Линия sleep 1 заключается в том, чтобы избежать избыточного потребления ЦП из оживленного ожидания. Вы можете изменить это на любой sleep duration, который вам нравится, если вы хотите только опросить температуру так часто.

4
ответ дан 23 May 2018 в 14:11

Это может сработать:

#!/bin/bash

targettemp=90
started=1

COMMAND &

trap "kill COMMAND; exit" SIGINT SIGTERM

while true
do
  currenttemp=$(sensors -u | awk '/temp1_input/ {print $2; exit}' )
  compare=$(echo $currenttemp'>'$targettemp | bc -l)
  if [ "$compare" -eq 1 ] && [ "$started" -eq 1 ] 
  then
    started=0
    kill -STOP COMMAND
  fi
  if [ "$compare" -eq 0 ] && [ "$started" -eq 0 ]
  then
    started=1
    kill -CONT COMMAND
  fi
  sleep 1 & wait $!
done

Это приведет к появлению текущего «temp1» результата от датчиков, обрезает любые другие символы, которые ему не нужны, чтобы bash мог видеть это как число, затем сравните его с любой заданной вами температурой. Мои рассуждения по поводу добавления «NR + 1000», а затем grep 1001 состоят в том, что в sensors у вас могут быть два результата «temp1», как и я. Это своего рода kludge, но он работает.

Затем, когда вы хотите его убить, просто killall script.sh.

Линия sleep 1 заключается в том, чтобы избежать избыточного потребления ЦП из оживленного ожидания. Вы можете изменить это на любой sleep duration, который вам нравится, если вы хотите только опросить температуру так часто.

4
ответ дан 23 May 2018 в 14:11

Это может сработать:

#!/bin/bash

targettemp=90
started=1

COMMAND &

trap "kill COMMAND; exit" SIGINT SIGTERM

while true
do
  currenttemp=$(sensors -u | awk '/temp1_input/ {print $2; exit}' )
  compare=$(echo $currenttemp'>'$targettemp | bc -l)
  if [ "$compare" -eq 1 ] && [ "$started" -eq 1 ] 
  then
    started=0
    kill -STOP COMMAND
  fi
  if [ "$compare" -eq 0 ] && [ "$started" -eq 0 ]
  then
    started=1
    kill -CONT COMMAND
  fi
  sleep 1 & wait $!
done

Это приведет к появлению текущего «temp1» результата от датчиков, обрезает любые другие символы, которые ему не нужны, чтобы bash мог видеть это как число, затем сравните его с любой заданной вами температурой. Мои рассуждения по поводу добавления «NR + 1000», а затем grep 1001 состоят в том, что в sensors у вас могут быть два результата «temp1», как и я. Это своего рода kludge, но он работает.

Затем, когда вы хотите его убить, просто killall script.sh.

Линия sleep 1 заключается в том, чтобы избежать избыточного потребления ЦП из оживленного ожидания. Вы можете изменить это на любой sleep duration, который вам нравится, если вы хотите только опросить температуру так часто.

4
ответ дан 23 May 2018 в 14:11

Другие вопросы по тегам:

Похожие вопросы: