web-dev-qa-db-ja.com

コア温度が特定の値を上回った/下回ったときにタスクを開始または強制終了する方法は?

手動で1度起動する短いスクリプトを記述したいと思います。

  • all温度がx°C未満の場合にコマンドを実行します。
  • any温度がy°Cを超えたらコマンドを一時停止します。
  • all温度が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
Byte Commander

このスクリプトは、その中で実行されているプロセスをルートとするプロセスツリー全体に影響します。

端末で実行し、_watch -n 1 'sensors -u | grep -Po "^ temp[0-9]+_input: \K.*"'_を使用して別の端末の温度を確認することで、簡単にテストできます。

この例では、しきい値は_50_と_75_に設定されており、プロセスの実行は_stress -c 3_です。これらはスクリプトにハードコードされていますが、スクリプトを変更して、引数。

すべての温度が50°C以下になるとすぐにstressが始まります。すべての温度が75°C未満にとどまる限り、stressは継続します。 1つの温度が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_の場合、プロセスが開始され、バックグラウンドに配置されてループから抜けます。

  • 2番目のwhileループは、_$maxtemp_を超える温度の数が_0_を超えるまで、無期限にアイドル状態になります。 _$maxtemp_を超える温度の数が_0_より大きい場合、SIGSTOPをプロセスグループに送信し、3番目のwhileループを開始します。 3番目のwhileループは、_$mintemp_を超える温度の数が_0_になるまで無期限にアイドル状態になります。 _$mintemp_を超える温度の数が_0_である場合、SIGCONTがプロセスグループに送信され、ループから抜けます。

2
kos

これはうまくいくかもしれません:

#!/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の追加全体の背後にある私の推論は、私がしたように、2つの "temp1"結果がsensorsになる可能性があるためです。それは一種のクラッジですが、動作します。

次に、それを強制終了する場合は、killall script.shだけです。

sleep 1行は、ビジー待機による過剰なCPU消費を回避するためのものです。温度を時々しかポーリングしない場合は、これを任意のsleep durationに変更できます。

4
user323419