Disons que j'ai 20 utilisateurs connectés sur ma boîte Linux. Comment savoir combien de mémoire chacun utilise?
Disons que j'ai 20 utilisateurs connectés sur ma boîte Linux. Comment savoir combien de mémoire chacun utilise?
Réponses:
Vous pouvez essayer d'utiliser smem (voir ELC2009: Visualisation de l'utilisation de la mémoire avec smem pour plus d'informations). En particulier, sudo smem -u
devrait vous donner les informations que vous souhaitez.
--no-install-recommends
.
Ignorant les problèmes de mémoire partagée, voici un script rapide qui vous donne RSS et VMEM pour tous les utilisateurs connectés, triés par vmem et organisés en colonnes mignonnes:
(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
Pour obtenir la somme de RSS, je pense que les œuvres suivantes. Ce serait d'obtenir la somme de RSS pour les utilisateurs kbrandt et root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
Voilà une question délicate. Vous pouvez facilement résumer le montant total des échanges RSS + dans la sortie "ps", mais qu'en est-il de la mémoire partagée? Différents utilisateurs peuvent facilement partager la même page de codes s'ils exécutent le même processus. À qui expliquez-vous cela? Qu'en est-il des tampons et du cache? Cela dépend vraiment de la précision de vos résultats. Plus vous voulez de précision, plus ce sera difficile.
Je ne sais pas comment signaler l'utilisation de la mémoire par utilisateur, mais si vous souhaitez contrôler leur utilisation, vous devriez rechercher ulimit. Il vous permettra de définir des limites matérielles et logicielles par utilisateur / groupe pour la mémoire et les autres ressources de votre système.
Vous pouvez essayer quelque chose comme:
ps auxU maxwell | awk '{memory + = $ 4}; END {print memory} '
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, où mysql pouvait être remplacé par le nom d'un utilisateur ou d'un processus.
En cherchant la même chose, j'ai compris
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
pour imprimer les processus ordonnés par mem, groupés par utilisateur (colonne1, le $ 1), vous pouvez grouper par d'autres choses, et additionner d'autres choses, en changeant $ 1 et $ 4
J'étais heureux de trouver la solution, je voulais juste partager.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. La commande sort a besoin de l' -n
indicateur pour lui permettre d'analyser la mémoire sous forme de nombre. De cette façon, vous pouvez également remplacer le mot «utilisateur» par «commande» pour regrouper par nom d'application.
Ce script bash est probablement moche comme l'enfer, mais merci pour l'exercice, mon bash rougissait!
#!/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
Résultat:
[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
Veuillez commenter / corriger et je mettrai à jour la réponse. J'utilise également la sortie mémoire rss de PS, comme d'autres l'ont expliqué, il y a des avantages / inconvénients à utiliser cette valeur.
smem n'était pas disponible sur mon système, et le script de Dave ne fonctionnait pas pour une raison quelconque, j'ai donc écrit ce laid onliner Perl pour traiter la sortie 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
Notez que certains utilisateurs ont été identifiés en utilisant leur UID plutôt que leur nom d'utilisateur. Vous pouvez résoudre ce problème en analysant les noms d'utilisateur de / etc / passwd, en utilisant le plus laid:
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
Utilisation de 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
PRODUCTION
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Eh bien, dans cet état du noyau Linux, je ne peux penser qu'à un seul moyen approprié d'accomplir cette tâche - en utilisant des groupes de mémoire. Vous auriez besoin de mettre un utilisateur à la connexion dans son propre groupe de contrôle, et cela pourrait nécessiter le développement de son propre module pam ou (plutôt) la modification du module existant pour cela.
Un document utile à lire à ce sujet est: Guide de gestion des ressources par RedHat®.