Часто возникает необходимость посмотреть суммарное потребление памяти группой однотипных процессов (кумулятивно). 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ю).