Часто возникает необходимость посмотреть суммарное потребление памяти группой однотипных процессов (кумулятивно). top и ps без обработки не сильно помогает, поэтому сегодня написал следующий скрипт:
Собственно скрипт
#!/bin/bash ps -eo pid,comm,user,%mem | awk ' { memory[$2]+=$4; } END { print( "--== Cumulative memory usage TOP: ==--" ); print( "--------------------------------------" ); print( "%MEM t| COMM" ); print( "--------------------------------------" ); while( length(memory) > 0 ) { max = -1; for( i in memory ) { if( memory[i]>max ) { max_index = i; max = memory[max_index]; } } delete memory[max_index]; print( max, "t| ", max_index ); } }' | less
Несколько комментариев:
- Сначала получаем список процессов при помощи ps. Выглядит он примерно так:
PID COMMAND USER %MEM 1 init root 0.0 2 migration/0 root 0.0 3 ksoftirqd/0 root 0.0 4 watchdog/0 root 0.0 5 migration/1 root 0.0 6 ksoftirqd/1 root 0.0
- Затем при помощи awk собираем кумулятивные данные в массив ( memory[$2]+=$4; ). Тут думаю все понятно.
- Последним штрихом является сортировка кумулятивных значений и их отображение. К сожалению asort, встроенный в gawk, выдавал что-то неудобоваримое, пришлось написать простую сортировку самостоятельно. Пока массив memory содержит элементы, пробегаем мессив memory, ищем максимальный элемент, печатаем его, удаляем максимальный элемент ( delete memory[max_index]; ). Каждую итерацию, массив memory уменьшается на один элемент.
- less добавлен для удобства использования.
Результат работы скрипта:
--== Cumulative memory usage TOP: ==-- -------------------------------------- %MEM | COMM -------------------------------------- 7.4 | httpd 3.1 | clamd 2.8 | spamd 0.6 | mysqld 0.4 | yum-updatesd 0.2 | named 0.1 | ntpd 0.1 | munin-node 0 | rpciod/1 0 | rpciod/2 0 | udevd
Боле короткая форма записи для скрипта (без сортировки, но в одну строку):
# ps -eo pid,comm,user,%mem | awk '{memory[$2]+=$4} END{ print( "%MEM t| COMM" ); for( proc in memory ) print( memory[proc], "t| ", proc ); }' | less
Have fun ))
p.s. Можно добавить еще распознавание и группировку таких процессов rpciod/1 и rpciod/2
p.p.s. Можно попробовать добавить обновление по времени like top, и ограничить число выводимых процессов (например 20ю).
при выполнении возникает ошибки:
awk: line 5: syntax error at or near end of line
awk: line 11: illegal reference to array memory
(END)
1 #!/bin/bash
2 ps -eo pid,comm,user,%mem | awk ‘
3 {
4 memory[$2]+=$4;
5 }
6 END
7 {
8 print( “–== Cumulative memory usage TOP: ==–” );
9 print( “————————————–” );
10 print( “%MEM t| COMM” );
11 print( “————————————–” );
12 while( length(memory) > 0 )
13 {
14 max = -1;
15 for( i in memory )
16 {
17 if( memory[i]>max )
18 {
19 max_index = i;
20 max = memory[max_index];
21 }
22 }
23 delete memory[max_index];
24 print( max, “t| “, max_index );
25 }
26 }’ | less
Предлагаете подебажить? А как же спортивный интерес? )))
P.S. Мои скрипты у меня работают – уж и не помню, в таком виде или нет…