Bash: подождите, пока загрузка процессора не станет ниже порога
В bash script мне нужно подождать, пока загрузка процессора не станет ниже порога.
Другими словами, мне нужна команда wait_until_cpu_low
, которую я бы использовал следующим образом:
# Trigger some background CPU-heavy command
wait_until_cpu_low 40
# Some other commands executed when CPU usage is below 40%
Как я могу это сделать?
Edit:
- целевая ОС: Red Hat Enterprise Linux Server release 6.5
- Я рассматриваю среднее использование ЦП (по всем ядрам)
Ответы
Ответ 1
wait_for_cpu_usage()
{
current=$(mpstat 1 1 | awk '$12 ~ /[0-9.]+/ { print int(100 - $12 + 0.5) }')
while [[ "$current" -ge "$1" ]]; do
current=$(mpstat 1 1 | awk '$12 ~ /[0-9.]+/ { print int(100 - $12 + 0.5) }')
sleep 1
done
}
Обратите внимание, что пакет sysstat установлен.
Ответ 2
Вы можете использовать функцию, основанную на утилите top
. Но учтите, что это не очень надежно, потому что загрузка процессора может - быстро - измениться в любое время. Это означает, что только потому, что проверка прошла успешно, не гарантируется, что загрузка процессора останется низкой, как только будет выполняться следующий код. Вы были предупреждены.
Функция:
function wait_for_cpu_usage {
threshold=$1
while true ; do
# Get the current CPU usage
usage=$(top -n1 | awk 'NR==3{print $2}' | tr ',' '.')
# Compared the current usage against the threshold
result=$(bc -l <<< "$usage <= $threshold")
[ $result == "1" ] && break
# Feel free to sleep less than a second. (with GNU sleep)
sleep 1
done
return 0
}
# Example call
wait_for_cpu_usage 25
Обратите внимание, что я использую bc -l
для сравнения, так как top печатает использование ЦП в качестве значения поплавка.
Ответ 3
Более эффективная версия просто вызывает mpstat
и awk
один раз каждый и удерживает их обоих до тех пор, пока они не будут выполнены; нет необходимости явно sleep
и перезапускать оба процесса каждую секунду (что на встроенной платформе может привести к измеримым служебным данным):
wait_until_cpu_low() {
awk -v target="$1" '
$13 ~ /^[0-9.]+$/ {
current = 100 - $13
if(current <= target) { exit(0); }
}' < <(mpstat 1)
}
Я использую $13
здесь, потому что там, где idle %
для моей версии mpstat; замените соответствующим образом, если ваш отличается.
Это имеет дополнительное преимущество в правильной математике с плавающей запятой, а не в округлении до целых чисел для математической оболочки оболочки.