Допустим, у меня есть 20 пользователей, вошедших в мою коробку Linux. Как я могу узнать, сколько памяти использует каждый из них?
Допустим, у меня есть 20 пользователей, вошедших в мою коробку Linux. Как я могу узнать, сколько памяти использует каждый из них?
Ответы:
Вы можете попробовать использовать smem (см. ELC2009: Визуализация использования памяти с помощью smem для получения дополнительной информации). В частности, sudo smem -u
должен дать вам информацию, которую вы хотите.
--no-install-recommends
.
Игнорируя проблемы с общей памятью, вот быстрый скрипт, который дает вам RSS и VMEM для всех вошедших в систему пользователей, сортирует по vmem и разбивает на симпатичные столбцы:
(echo "user rss(KiB) vmem(KiB)";
for user in $(users | tr ' ' '\n' | sort -u); do
echo $user $(ps -U $user --no-headers -o rss,vsz \
| awk '{rss+=$1; vmem+=$2} END{print rss" "vmem}')
done | sort -k3
) | column -t
Чтобы получить сумму RSS, я думаю, что следующие работы. Это будет для получения суммы RSS для пользователей kbrandt и root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
Это сложный вопрос. Вы можете легко суммировать общее количество RSS + подкачки в выводе "ps", но как насчет общей памяти? Разные пользователи могут легко использовать одну и ту же кодовую страницу, если они запускают один и тот же процесс. Кому вы это объясняете? А как насчет буферов и кеша? Это действительно зависит от того, насколько точным вы хотите, чтобы ваши результаты были. Чем точнее вы хотите, тем сложнее будет.
Я не уверен, как сообщить об использовании памяти пользователем, но если вы беспокоитесь об управлении его использованием, то вам следует поискать ulimit. Это позволит вам установить жесткие и мягкие ограничения для каждого пользователя / группы для памяти и других ресурсов в вашей системе.
Вы можете попробовать что-то вроде:
PS AUXU Максвелл | awk '{memory + = $ 4}; END {печать памяти} '
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, где mysql может быть заменен именем пользователя или процесса.
В поисках того же я разобрался с этим
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
для печати процессов, упорядоченных по mem, сгруппированных по пользователю (колонка 1, $ 1), вы можете группировать по другим вещам и суммировать другие вещи, изменяя $ 1 и $ 4
Я был рад найти решение, просто хотел поделиться.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. Команде sort нужен -n
флаг, чтобы она анализировала память как число. Также таким образом вы можете заменить слово «пользователь» словом «команда», чтобы группировать по имени приложения.
Этот сценарий bash, вероятно, ужасен, но спасибо за упражнение, мой bash стал (становится) ржавым!
#!/bin/sh
OLDIFS=$IFS
IFS=$'\n'
tempsum=0
totalmem=0
for m in `ps -eo user,rss --sort user | sed -e 's/ */ /g' | awk -F'[ ]' {'print $0'}`; do
nu=`echo $m|cut -d" " -f1`
nm=`echo $m|cut -d" " -f2`
# echo "$nu $nm $nu"
if [ "$nu" != "$ou" ] && [ $(echo "$nm"|grep -E "^[0-9]+$") ]
then
if [ "$tempsum" -ne 0 ]; then echo "Printing total mem for $ou: $tempsum"; fi
ou=$nu
tempsum=$nm
let "totalmem += $nm"
else
let "tempsum += $nm"
let "totalmem += $nm"
fi
done
echo "Total Memory in Use: $totalmem/$(free | grep Mem: | awk '{print $2}')"
IFS=$OLDIFS
Результат:
[20:34][root@server2:~]$ ./memorybyuser.sh
Printing total mem for admin: 1387288
Printing total mem for apache: 227792
Printing total mem for avahi: 1788
Printing total mem for dbus: 980
Printing total mem for 68: 3892
Printing total mem for root: 55880
Printing total mem for rpc: 292
Printing total mem for rpcuser: 740
Printing total mem for smmsp: 720
Printing total mem for xfs: 680
Total Memory in Use: 1682360/4152144
Пожалуйста, прокомментируйте / исправьте, и я обновлю ответ. Также я использую вывод памяти rss от PS, поскольку другие обсуждали, что есть плюсы / минусы использования этого значения.
SEMM не был доступен в моей системе, и сценарий Дэйва по какой-то причине не работал, поэтому я написал этот уродливый Perl-oneliner для обработки вывода ps:
ps -eo user,rss | perl -e 'foreach (<>) { m/(\w+)\s+(\d+)/; $mem{$1} += $2; }; foreach $u (keys %mem) { if ($mem{$u}) { print "$u - $mem{$u}\n" }}' | sort
Обратите внимание, что некоторые пользователи были идентифицированы по их UID, а не по имени пользователя. Вы можете справиться с этим, проанализировав имена пользователей из / etc / passwd, используя uglier:
ps -eo user,rss | perl -e 'open(F, "/etc/passwd"); foreach $l (<F>) { if ($l=~/(.*?):.*?:(\d+)/) { $users{$2}=$1; }}; foreach (<>) { m/(\w+)\s+(\d+)/; $mem{$1} += $2; }; foreach $u (keys (%mem)) { $UN = $u; if ($UN=~/^\d+$/) { $UN = $users{$UN};}; if ($mem{$u}) { print "$UN - $mem{$u}\n" }}' | sort
Использование Bash Script
#!/bin/bash
total_mem=0
printf "%-10s%-10s\n" User MemUsage'(%)'
while read u m
do
[[ $old_user != $u ]] && { printf "%-10s%-0.1f\n" $old_user $total_mem;
total_mem=0; }
total_mem="$(echo $m + $total_mem | bc)"
old_user=$u
done < <(ps --no-headers -eo user,%mem| sort -k1)
#EOF
ВЫХОД
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Что ж, в этом состоянии ядра Linux я могу придумать только один правильный способ решения этой задачи - использование cgroups памяти. Вам нужно будет ввести пользователя при входе в собственную группу, и для этого может потребоваться разработка собственного модуля pam или (скорее) изменение существующего модуля для этого.
Полезный документ для прочтения: Руководство по управлению ресурсами от RedHat®.