Giả sử tôi có 20 người dùng đăng nhập vào hộp linux của mình. Làm thế nào tôi có thể biết mỗi bộ nhớ đang sử dụng bao nhiêu bộ nhớ?
Giả sử tôi có 20 người dùng đăng nhập vào hộp linux của mình. Làm thế nào tôi có thể biết mỗi bộ nhớ đang sử dụng bao nhiêu bộ nhớ?
Câu trả lời:
Bạn có thể thử sử dụng smem (xem ELC2009: Trực quan hóa việc sử dụng bộ nhớ với smem để biết thêm thông tin). Đặc biệt, sudo smem -u
nên cung cấp cho bạn thông tin bạn muốn.
--no-install-recommends
.
Bỏ qua các vấn đề về bộ nhớ được chia sẻ, đây là tập lệnh nhanh cung cấp cho bạn RSS và VMEM cho tất cả người dùng đã đăng nhập, được sắp xếp theo vmem và sắp xếp thành các cột dễ thương:
(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
Để có được tổng số RSS tôi nghĩ rằng các công việc sau đây. Điều này sẽ là để có được tổng số RSS cho người dùng kbrandt và root.
ps -U kbrandt,root --no-headers -o rss | (tr '\n' +; echo 0) | bc
Đó là một câu hỏi khó. Bạn có thể dễ dàng tổng hợp tổng số lượng trao đổi RSS + trong đầu ra "ps", nhưng còn bộ nhớ dùng chung thì sao? Những người dùng khác nhau có thể dễ dàng chia sẻ cùng một trang mã nếu họ đang chạy cùng một quy trình. Bạn làm tài khoản đó cho ai? Còn bộ đệm và bộ đệm thì sao? Nó thực sự phụ thuộc vào mức độ chính xác mà bạn muốn kết quả của bạn. Bạn càng chính xác, bạn sẽ càng khó.
Tôi không chắc chắn làm thế nào để báo cáo việc sử dụng bộ nhớ của người dùng nhưng nếu bạn lo lắng về việc kiểm soát việc sử dụng bộ nhớ thì bạn nên tìm kiếm ulimit. Nó sẽ cho phép bạn đặt giới hạn cứng và mềm trên cơ sở cho mỗi người dùng / nhóm cho bộ nhớ và các tài nguyên khác trên hệ thống của bạn.
Bạn có thể thử một cái gì đó như:
ps maxU maxwell | awk '{bộ nhớ + = $ 4}; HẾT {bộ nhớ in} '
ps aux | grep mysql | awk '{memory +=$4}; END {print memory }'
, nơi mysql có thể được thay thế bằng tên của người dùng hoặc quá trình.
Tìm kiếm tương tự, tôi đã tìm ra điều này
ps aux | awk '{arr[$1]+=$4}; END {for (i in arr) {print i,arr[i]}}' | sort -k2
để in các quy trình được sắp xếp theo mem, được nhóm theo người dùng (cột 1, $ 1), bạn có thể nhóm theo những thứ khác và tổng hợp những thứ khác, thay đổi $ 1 và $ 4
Tôi rất vui khi tìm thấy giải pháp, chỉ muốn chia sẻ.
ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]}}' | sort -nk2
. Lệnh sort cần -n
cờ để phân tích bộ nhớ dưới dạng số. Ngoài ra, bằng cách này, bạn có thể thay thế từ "người dùng" bằng "lệnh" để nhóm theo tên ứng dụng.
Kịch bản bash này có lẽ xấu như địa ngục, nhưng cảm ơn bạn vì đã tập thể dục, bash của tôi đã (đang) trở nên rỉ sét!
#!/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
Kết quả:
[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
Hãy bình luận / chính xác và tôi sẽ cập nhật câu trả lời. Ngoài ra tôi sử dụng đầu ra bộ nhớ rss từ PS, như những người khác đã thảo luận có những ưu / nhược điểm khi sử dụng giá trị này.
smem không có sẵn trên hệ thống của tôi và kịch bản của Dave không hoạt động vì một số lý do, vì vậy tôi đã viết oneliner xấu xí này để xử lý đầu ra 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
Lưu ý rằng một số người dùng đã được xác định bằng UID của họ thay vì tên người dùng của họ. Bạn có thể giải quyết vấn đề này bằng cách phân tích tên người dùng từ / etc / passwd, bằng cách sử dụng xấu hơn:
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
Sử dụng 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
ĐẦU RA
User MemUsage(%)
apache 4.8
dbus 0.0
mysql 3.8
nagios 3.1
Chà, ở trạng thái nhân Linux này, tôi chỉ có thể nghĩ ra một cách thích hợp để hoàn thành nhiệm vụ này - sử dụng các nhóm bộ nhớ. Bạn cần đưa người dùng đăng nhập vào nhóm riêng của mình và điều này có thể yêu cầu phát triển mô-đun pam riêng hoặc (thay vì) sửa đổi mô-đun hiện có cho điều đó.
Tài liệu hữu ích để đọc về điều này là: Hướng dẫn quản lý tài nguyên của RedHat®.