Diciamo che ho 20 utenti registrati sulla mia scatola di Linux. Come posso sapere quanta memoria sta usando ognuno di loro?
Diciamo che ho 20 utenti registrati sulla mia scatola di Linux. Come posso sapere quanta memoria sta usando ognuno di loro?
Risposte:
È possibile provare a utilizzare smem (consultare ELC2009: visualizzazione dell'utilizzo della memoria con smem per ulteriori informazioni). In particolare, sudo smem -u
dovrebbe darti le informazioni che desideri.
--no-install-recommends
.
Ignorando i problemi di memoria condivisa, ecco uno script veloce che ti fornisce RSS e VMEM per tutti gli utenti che hanno effettuato l'accesso, ordinati per vmem e organizzati in graziose colonne:
(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
Per ottenere la somma di RSS penso che i seguenti lavori. Questo sarebbe quello di ottenere la somma di RSS per gli utenti kbrandt e root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
Questa è una domanda difficile. Potresti facilmente riassumere gli importi di scambio RSS + totali nell'output "ps", ma che dire della memoria condivisa? Utenti diversi potrebbero facilmente condividere la stessa tabella codici se eseguono lo stesso processo. Con chi lo conti? Che dire di buffer e cache? Dipende davvero dalla precisione con cui vuoi che i tuoi risultati siano. Più preciso vuoi, più difficile sarà.
Non sono sicuro su come segnalare l'utilizzo della memoria da parte dell'utente, ma se sei preoccupato di controllarne l'utilizzo, dovresti cercare ulimit. Ti consentirà di impostare limiti rigidi su base per utente / gruppo per la memoria e altre risorse sul tuo sistema.
Puoi provare qualcosa del tipo:
ps auxU maxwell | awk '{memory + = $ 4}; END {memoria di stampa} '
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, dove mysql potrebbe essere sostituito con il nome di un utente o processo.
Cercando lo stesso, ho capito questo
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
per stampare i processi ordinati per mem, raggruppati per utente (colonna1, $ 1), puoi raggruppare per altre cose e sommare altre cose, cambiando $ 1 e $ 4
Sono stato felice di trovare la soluzione, volevo solo condividere.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. Il comando sort ha bisogno del -n
flag per far analizzare la memoria come un numero. Inoltre, in questo modo è possibile sostituire la parola "utente" con "comando" per raggruppare in base al nome dell'applicazione.
Questa sceneggiatura di Bash è probabilmente brutta da morire, ma grazie per l'esercizio, la mia bash stava (sta) diventando arrugginita!
#!/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
Risultato:
[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
Si prega di commentare / correggere e aggiornerò la risposta. Inoltre uso l'output di memoria rss di PS, poiché altri hanno discusso che ci sono vantaggi / svantaggi nell'usare questo valore.
smem non era disponibile sul mio sistema e la sceneggiatura di Dave non funzionava per qualche motivo, quindi ho scritto questo orribile programma Perl per elaborare l'output 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
Si noti che alcuni utenti sono stati identificati utilizzando il proprio UID anziché il proprio nome utente. Puoi gestirlo analizzando i nomi utente da / etc / passwd, usando il più brutto:
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
Utilizzando 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
PRODUZIONE
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Bene, in questo stato del kernel Linux posso pensare a un solo modo corretto di compiere questo compito - usare i cgroup di memoria. Dovresti mettere un utente al login nel proprio cgroup, e questo potrebbe richiedere il proprio sviluppo del modulo pam o (piuttosto) modificare il modulo esistente per quello.
Documento utile da leggere al riguardo è: Guida alla gestione delle risorse di RedHat®.