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

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

  • выполните команду, если все температуры ниже 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. Если это не будет работать с Вашим решением (например, потому что оно зарегистрирует любые запланированные события для опроса температуры), мне нужна отдельная команда для выхода из него.

Как я могу записать этот сценарий?

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

3 ответа

Этот сценарий будет влиять на целое дерево процесса, базированное при процессе, выполненном в нем.

Можно легко протестировать его путем выполнения его в терминале и проверки температур в другое терминальное использование watch -n 1 'sensors -u | grep -Po "^ temp[0-9]+_input: \K.*"'.

В этом примере пороги устанавливаются к 50 и 75 и выполненный процесс stress -c 3: они трудно кодируются в сценарий, но легко изменить сценарий для чтения их из аргументов.

Как только все температуры будут ниже 50°C stress запустится; пока все температуры останутся ниже 75°C stress продолжится; как только одна температура будет выше 75°C stress остановится; как только все температуры будут ниже 50°C снова stress продолжится снова:

#!/bin/bash
function n_t_exceeding {
    sensors -u | awk -v x=0 -v temp=$1 '$1~/^temp[0-9]+_input:/{if($2 > temp){x++}}END{print x}'
}
set -m # Enables job control
mintemp=50 # First threshold
maxtemp=75 # Second threshold
while true; do
    if [ $(n_t_exceeding $mintemp) -eq 0 ]; then
        stress -c 3 & pid=$! # Starts the process, backgrounds it and stores the process' PID
        printf 'Started\n'
        break
    fi
    sleep 1 & wait $!
done
trap 'pkill -g $pid; exit' 2 # Upon SIGINT, sends SIGTERM to the process group and exits
while true; do
    if [ $(n_t_exceeding $maxtemp) -gt 0 ]; then
        pkill -19 -g $pid # Sends SIGSTOP to the process group
        printf 'Stopped\n'
        while true; do
            if [ $(n_t_exceeding $mintemp) -eq 0 ]; then
                pkill -18 -g $pid # Sends SIGCONT to the process group
                printf 'Resumed\n'
                break
            fi
            sleep 1 & wait $!
        done
    fi
    sleep 1 & wait $!
done
  • function n_t_exceeding { sensors -u | awk -v x=0 -v temp=$1 '$1~/^temp[0-9]+_input:/{if($2 > temp){x++}}END{print x}'; } анализирует вывод sensors -u и печатает количество температур выше $1 (который является первым аргументом, переданным функции):

    % sensors -u
    acpitz-virtual-0
    Adapter: Virtual device
    temp1:
      temp1_input: 45.000
      temp1_crit: 108.000
    
    asus-isa-0000
    Adapter: ISA adapter
    cpu_fan:
      fan1_input: 2200.000
    temp1:
      temp1_input: 45.000
    
    coretemp-isa-0000
    Adapter: ISA adapter
    Physical id 0:
      temp1_input: 47.000
      temp1_max: 87.000
      temp1_crit: 105.000
      temp1_crit_alarm: 0.000
    Core 0:
      temp2_input: 46.000
      temp2_max: 87.000
      temp2_crit: 105.000
      temp2_crit_alarm: 0.000
    Core 1:
      temp3_input: 47.000
      temp3_max: 87.000
      temp3_crit: 105.000
      temp3_crit_alarm: 0.000
    
    % sensors -u | awk -v x=0 -v temp=46 '$1~/^temp[0-9]+_input:/{if($2 > temp){x++}}END{print x}'
    2
    
  • set -m включает управление заданиями;

  • mintemp=50; maxtemp=75 наборы $mintemp и $maxtemp кому: 50 и 75 соответственно; это пороги 1), ниже которых процесс должен запуститься в первый раз и продолжиться снова превысив $maxtemp 2) выше которого должен остановиться процесс;

  • trap 'pkill -g $pid; exit' 2 удостоверяется, что сценарий завершит все процессы в группе процесса и выходе на CTRL+C;

  • Первое while цикл бездействует неограниченно долго до количества температур $mintemp 0; когда количество температур $mintemp 0 запускает процесс, помещает его в фон и убегает из цикла;

  • Второе while цикл бездействует неограниченно долго до количества температур $maxtemp больше, чем 0; когда количество температур $maxtemp больше, чем 0 отправляет SIGSTOP группе процесса и запускает одну треть while цикл; третье while цикл бездействует неограниченно долго до количества температур $mintemp 0; когда количество температур $mintemp 0 отправляет SIGCONT группе процесса и убегает из цикла.

2
ответ дан 3 December 2019 в 06:22

Это могло бы работать:

#!/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" датчиков, обрезка любые другие символы, в которых это не нуждается так, чтобы удар видел его, поскольку число, затем сравните его с любой целевой температурой, которую Вы устанавливаете.
Мое обоснование позади целого добавления "NR+1000" и затем grep 1001 состоит в том, потому что у Вас могло бы быть два результата "temp1" в sensors, как я сделал. Это - вид клуджа, но это работает.

Затем когда Вы хотите уничтожить его, всего killall script.sh.

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

4
ответ дан 3 December 2019 в 06:22

Сценарий

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

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

  1. Скопируйте сценарий в пустой файл, сохраните его как temp_run.py
  2. Выполните его, лучше всего перед выполнениями процесса (сценарий запустит процесс), с (впоследствии) low_temp, high_temp, process_name и возможные аргументы, как аргументы. Я протестировал его, например, с:

    python3 /path/to/temp_run.py 60 80 gedit /path/to/file.txt
    

    (использующий другого редактора простого текста для изменения числа)

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

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

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

Как это работает

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

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

Как уничтожить его

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

kill "$(pgrep -f temp_run.py)"
2
ответ дан 3 December 2019 в 06:22

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

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