Начиная с команды sar 1 1
:
# sar 1 1
Linux 4.14.14 (sys.local) 02/08/2018 _x86_64_ (4 CPU)
09:38:01 PM CPU %user %nice %system %iowait %steal %idle
09:38:02 PM all 5.74 0.00 1.50 0.00 0.00 92.77
Average: all 5.74 0.00 1.50 0.00 0.00 92.77
Нам нужен столбец% iowait. Распространенная строка соответствует регулярному выражению против в каждой строке all
под CPU
так что :
# sar 1 1 | awk '/all|iowait/{print $7}'
%iowait
0.00
0.00
В этом случае мы добавили iowait
к регулярному выражению, чтобы подтвердить, что мы получили правильный столбец, $7
. (Смотрите man awk
для более подробной информации об использовании awk.) Наш следующий шаг - сохранить эти значения для использования в нашем скрипте:
# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) )
Этот синтаксис var=()
предназначен для массива. Смотрите man bash
для деталей. Мы можем ссылаться на эти значения с помощью $ {iowait [1]}, так что теперь мы готовы к циклу над обоими значениями:
# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; for I in ${iowait[*]} ; do \
echo $I ; \
done
0.25
0.00
Отлично, почти нет, нет, мы можем сравнить эти значения с условными. Это потребует дополнительных усилий, потому что bash предпочитает сравнивать целые числа, а не с плавающей точкой. Мы могли бы умножить их на 100 перед сравнением, но проще использовать ярлык bash, чтобы отбрасывать десятичные дроби перед сравнением. Чтобы получить 12 из 12.34 в переменной $I
, мы будем использовать синтаксис $ {I %%. *}. Это удаляет совпадающий суффикс из переменной I
, а регулярное выражение .*
Сопоставляет что угодно, то есть все после десятичной дроби. -lt
в bash будет работать в условном выражении : if [ ]; then something; fi
Все это подробно изложено в man bash
для справки.
# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
for I in ${iowait[*]} ; do \
if [ ${I%%.*} -lt 2 ] ; then \
echo "$I < 2" ; \
fi ; \
done
0.00 < 2
0.00 < 2
Последнее добавление, прежде чем мы отправим нашу электронную почту, давайте добавим определенную временную метку и посмотрим, что работает во время этого высокого ввода-вывода:
# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
for I in ${iowait[*]} ; do \
if [ ${I%%.*} -lt 2 ] ; then \
echo "$(date -Is): iowait = $I\n $(ps)" ; \
fi ; \
done
2018-02-08T22:09:21-05:00: iowait = 0.25
PID TTY TIME CMD
3431 pts/1 00:00:00 zsh
28148 pts/1 00:00:00 ps
2018-02-08T22:09:21-05:00: iowait = 0.00
PID TTY TIME CMD
3431 pts/1 00:00:00 zsh
28150 pts/1 00:00:00 ps
Конечно, вы можете использовать лучшие опции ps, такие как ps eaf
или ps auxfw
, если хотите больше узнать. Нет, чтобы на самом деле выполнить задачу (сравнение -gt 50
) и отправить электронное письмо, отправив наш вывод mailx
:
# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
for I in ${iowait[*]} ; do \
if [ ${I%%.*} -gt 50 ] ; then echo "$(date -Is): iowait = $I\n $(ps)" |
mailx -s "hi iowait" root ; \
fi ; \
done
Надеемся, что это ответит и на ваш вопрос, и продемонстрирует, как можно построить то, что вы хотите, шаг за шагом разбирая проблему, используя философию Unix, множество инструментов и справочные страницы.