2012-05-24 42 views
0

我有一個問題,我無法解決,所以我來找你。Bash - 內存使用

我需要編寫一個程序來讀取所有進程,程序必須按用戶對它們進行排序,並且對於每個用戶,它必須顯示使用了多少內存。

例如:

USER1:120MB
用戶2:300MB
用戶3:50MB
總:470MB

我想用的ps aux命令來做到這一點,然後得到了PID和用戶用awk命令。然後用pmap我只需要獲得一個進程的全部內存使用情況。

+1

http://serverfault.com/questions/30994/memory-usage-per-user-in-linux – jordanm

+1

不要使用'pmap' - 使用'rss'或'size' 'ps'的字段。 –

回答

1

它只是一個小更新,用戶會自動選擇

#!/bin/bash 
function mem_per_user { 
    # take username as only parameter 
    local user=$1 
    # get all pid's of a specific user 
    # you may elaborate the if statement in awk obey your own rules 
    pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'` 

    local totalmem=0 
    for pid in $pids 
    do 
     mem=`pmap $pid | tail -1 | \ 
      awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'` 
     # when variable properly set 
     if [ ! -z $mem ] 
     then 
      totalmem=$((totalmem + $mem)) 
     fi 
    done 

    echo $totalmem 
} 

total_mem=0 
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq` 
do 
    per_user_memory=0 
    per_user_memory=$(mem_per_user $username) 
    if [ "$per_user_memory" -gt 0 ] 
    then 
     total_mem=$(($total_mem + $per_user_memory)) 

     echo "$username: $per_user_memory KB" 
    fi 
done 
echo "Total: $total_mem KB" 
+0

正如我從代碼中看到的,這一定是它。但有一個問題:awk:第1行:語法錯誤處於或接近, 這會顯示多次,所以它可能在循環awk中出錯(在函數中)?你能解決這個問題嗎?非常感謝你!問候 – golobich

0

您可以使用子流程模塊訪問python中的shell命令。它允許你產生子進程並連接到out/in /錯誤。您可以執行ps -aux命令並在python中解析輸出。

check out the docs here

+0

我沒有權限使用pythone或任何其他語言。只是bash。它必須全部寫在bash中。歐和一個更多的想法。它必須有.sh擴展名。這不會是一個問題。但我仍在尋求解決前一個問題的方法。謝謝 – golobich

1

試試這個腳本,它可以解決你的問題:

#!/bin/bash 
function mem_per_user { 
    # take username as only parameter 
    local user=$1 
    # get all pid's of a specific user 
    # you may elaborate the if statement in awk obey your own rules 
    pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'` 

    local totalmem=0 
    for pid in $pids 
    do 
     mem=`pmap $pid | tail -1 | \ 
      awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'` 
     # when variable properly set 
     if [ ! -z $mem ] 
     then 
      totalmem=$((totalmem + $mem)) 
     fi 
    done 

    echo $totalmem 
} 

total_mem=0 
for i in `seq 1 $#` 
do 
    per_user_memory=0 
    eval username=\$$i 
    per_user_memory=$(mem_per_user $username) 
    total_mem=$(($total_mem + $per_user_memory)) 

    echo "$username: $per_user_memory KB" 
done 
echo "Total: $total_mem KB" 

最好的問候!

+0

Summer_More_More_Tea,感謝你的這段代碼,但是當我試圖在./memory.sh中以終端的方式運行它時,上面的腳本只顯示:total:0KB。 有什麼建議我做錯了什麼? – golobich

+0

歡迎你。你有沒有指定用戶名?該腳本將所有用戶名作爲由空格('')分隔的參數。例如,你想檢查用戶'summer_more_more_tea'和'root'使用的所有內存,命令是'./memory.sh summer_more_more_tea root'。希望有幫助。:) –

+0

Summer_More_More_Tea,我沒有提供用戶名作爲參數。但是我會努力的!非常感謝您的幫助! ;) 但是,你能修改腳本,所以我不需要提供用戶名作爲參數? cat/etc/passwd |切-d:-f1 - >這顯示所有用戶,所以我認爲這會有所幫助。然後,對於每個用戶腳本,必須在該腳本中寫入時顯示內存使用情況。因爲將腳本作爲./memory.sh運行非常重要,不需要任何參數 還有一點,seq 1 $#的含義是什麼? 關心! – golobich

0

這裏是我的版本。我認爲Tim的版本無法正常工作,KB中的值太大。我認爲應該使用pmap -x命令中的RSS列來提供更準確的值。但請注意,你不能總是得到正確的值,因爲進程可以共享內存。閱讀本A way to determine a process's "real" memory usage, i.e. private dirty RSS?

#!/bin/bash 
if [ "$(id -u)" != "0" ]; then 
echo "WARNING: you have to run as root if you want to see all users" 
fi 
echo "Printing only users that current memmory usage > 0 Kilobytes " 
all=0 
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq` 
do 
pids=`ps aux | grep $username | awk -F" " '{print $2}'` 
total_memory=0 
for pid in $pids 
do 
    process_mem=`pmap -x $pid | tail -1 | awk -F" " '{print $4}'` 

    if [ ! -z $process_mem ] 
    then #don't try to add if string has no length 
    total_memory=$((total_memory+$process_mem)) 
    fi 
done 
#print only those that use any memmory 
if [ $total_memory -gt 0 ] 
then 
total_memory=$((total_memory/(1024))) 
echo "$username : $total_memory MB" 
all=$((all+$total_memory)) 
fi 
done 
echo "----------------------------------------" 
echo "Total: $all MB" 
echo "WARNING: Use at your own risk"