手動で1度起動する短いスクリプトを記述したいと思います。
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
。これがソリューションで機能しない場合(たとえば、スケジュールされたイベントを登録して温度をポーリングするため)、それを終了する別のコマンドが必要です。
このスクリプトを作成するにはどうすればよいですか?
このスクリプトは、その中で実行されているプロセスをルートとするプロセスツリー全体に影響します。
端末で実行し、_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がプロセスグループに送信され、ループから抜けます。
これはうまくいくかもしれません:
#!/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
に変更できます。