Powiedzmy, że mam 20 użytkowników zalogowanych na moim Linux-ie. Skąd mam wiedzieć, ile pamięci zużywa każde z nich?
Powiedzmy, że mam 20 użytkowników zalogowanych na moim Linux-ie. Skąd mam wiedzieć, ile pamięci zużywa każde z nich?
Odpowiedzi:
Możesz spróbować użyć smem ( więcej informacji znajdziesz w ELC2009: Wizualizacja użycia pamięci za pomocą smem ). W szczególności sudo smem -u
powinien dać ci potrzebne informacje.
--no-install-recommends
.
Ignorując problemy z pamięcią współużytkowaną, oto krótki skrypt, który udostępnia RSS i VMEM wszystkim zalogowanym użytkownikom, posortowane według vmem i uporządkowane w urocze kolumny:
(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
Aby uzyskać sumę RSS, myślę, że następujące prace. Byłoby to uzyskać sumę RSS dla użytkowników kbrandt i root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
To trudne pytanie. Możesz z łatwością zsumować całkowite kwoty wymiany + swap na wyjściu „ps”, ale co z pamięcią współdzieloną? Różni użytkownicy mogą łatwo udostępniać tę samą stronę kodową, jeśli uruchamiają ten sam proces. Komu to rozliczasz? Co z buforami i pamięcią podręczną? To zależy od dokładności wyników. Im dokładniej chcesz, tym trudniej będzie.
Nie jestem pewien, jak zgłosić zużycie pamięci przez użytkownika, ale jeśli martwisz się kontrolowaniem ich wykorzystania, powinieneś poszukać ulimit. Umożliwi to ustawienie twardych i miękkich limitów dla pamięci użytkownika i grupy w systemie.
Możesz spróbować czegoś takiego:
ps auxU maxwell | awk '{memory + = 4 $}; END {pamięć drukowania} ”
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, gdzie mysql można zastąpić nazwą użytkownika lub procesu.
Szukając tego samego, doszedłem do tego
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
aby wydrukować procesy uporządkowane według mem, pogrupowane według użytkownika (kolumna 1, 1 $), możesz grupować według innych rzeczy i sumować inne rzeczy, zmieniając 1 i 4 $
Z przyjemnością znalazłem rozwiązanie, chciałem się tylko podzielić.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. Polecenie sortowania wymaga -n
flagi, aby parsować pamięć jako liczbę. Również w ten sposób możesz zastąpić słowo „użytkownik” słowem „polecenie”, aby zamiast tego pogrupować według nazwy aplikacji.
Ten skrypt bashowy jest prawdopodobnie brzydki jak diabli, ale dziękuję za ćwiczenie, mój bash był zardzewiały!
#!/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
Wynik:
[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
Proszę skomentować / poprawić, a ja zaktualizuję odpowiedź. Używam również wyjścia pamięci rss z PS, ponieważ inni mówili, że używanie tej wartości ma zalety / wady.
smem nie był dostępny w moim systemie, a skrypt Dave'a z jakiegoś powodu nie działał, więc napisałem ten brzydki oneliner Perla do przetwarzania danych wyjściowych 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
Pamiętaj, że niektórzy użytkownicy zostali zidentyfikowani przy użyciu swojego identyfikatora UID zamiast nazwy użytkownika. Można sobie z tym poradzić, analizując nazwy użytkowników z / etc / passwd, używając narzędzia brzydszego:
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
Korzystanie ze skryptu Bash
#!/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
WYNIK
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Cóż, w tym stanie jądra Linuksa mogę wymyślić tylko jeden właściwy sposób na wykonanie tego zadania - użycie grup pamięci. Będziesz musiał umieścić użytkownika podczas logowania we własnej grupie, a to może wymagać opracowania własnego modułu pam lub (raczej) modyfikacji do tego celu istniejącego modułu.
Przydatnym dokumentem do przeczytania na ten temat jest: Przewodnik zarządzania zasobami firmy RedHat®.