2

Я новичок в написании сценариев, и я знаю, что вопрос ниже очень прост, но ничего не получается ..

Команда sar дает следующий вывод,

root@virt01:~# sar 1 1

Linux 3.19.0-42-generic (virt01.ubuntu.com)     13/02/16        _x86_64_        (1 CPU)

12:19:55        CPU     %user     %nice   %system   %iowait    %steal     
%idle

12:19:56        all      0.00      0.00      0.00      0.00      0.00    
100.00
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00
root@virt01:~#

Просто хочу узнать, как проверить конкретное значение, например:% iowait и отправить уведомление по электронной почте, если оно превышает 50.

Если вы можете помочь, я был бы благодарен.

Благодарю.

1 ответ1

1

Начиная с команды 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, множество инструментов и справочные страницы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .