2012-05-30 65 views
1

我有这样的代码:为什么我的代码不能按我想要的那样工作?

total=0; 
ps -u $(whoami) --no-headers | awk {'print $1'} | while read line; 
          do vrednost=$(pmap $line | tail -n1 | column -t | cut -d" " -f3 | tr "K" " "); 
          total=$((vrednost + total)) 
          echo $total 
          done 
          echo total: $total 

正如你看到的,我的代码总和我的所有进程的使用。当我每次都回复我的总数时,它运行正常,但最后...当我想要总数为一个值(echo total: $total)时,它仍然为零。但之前(在while)有正确的价值。

+0

不回答你的问题,但你可以声明'total'使用'声明-i总的“整数”属性具有= 0',然后简单地说'总+ = $ vrednost'。 – chepner

+0

@chepner:你也可以在有或没有声明变量为整数的情况下做'((total + = vrednost))'。对我来说,这样做明确表示你的意思是加法而不是连接。 –

回答

0

试试这个

#!/bin/bash 
total=0; 
for line in `ps -u $(whoami) --no-headers | awk {'print $1'}`; 
do 
    vrednost=$(pmap $line | tail -n1 | column -t | cut -d" " -f3 | tr "K" " "); 
     total=$(($vrednost + $total)) 
     echo $total 
done 
echo "total: $total" 
+0

ps -u $(whoami)--no-headers | awk {'print $ 1'}; 它说,这有一个错误...我不知道如何解决它:/ – Blaz

+0

OH YEAH ----它的工作我fogot'' – Blaz

+0

非常感谢! – Blaz

0

让我们削减你需要:)

declare -i total=0 
for size in $(ps -u $(whoami) --no-header -o vsz); do 
    total+=$size 
done 
echo $total 

首先,使用各种选项ps产生额外的进程数所需的进程大小列表,以千字节为单位。使用bash for-loop迭代该列表,使用'integer'属性声明的参数保持运行总数,以便于算术。所需的金额现在在total,准备好任何你需要的用途。总和包括ps进程本身使用的内存。

使用while(丹尼斯的建议),避免进程替换(威廉的建议):

ps -u $(whoami) --no-header -o vsz | { 
    while read -r var; do 
    ((total+=$var)) 
    done 
    echo $total 
} 

(真正的一行,这里有一个dc命令,我从https://stackoverflow.com/a/453290/1126841借:

ps -u $(whoami) --no-header -o vsz | dc -f - -e '[+z1<r]srz1<rp' 

这笔款项包括由psdc命令本身使用的内存。)

+0

大多数情况下,使用'for'来遍历命令替换是不正确的。因此,使用'while read -r var'代替它是很好的习惯。 –

1

好的,挑选。你可以在BASH或AWK中完成,但不要两者兼而有之。你见过一个BASH例如,这里有一个AWK例如:

ps -e -o user -o vsz | awk -v USER="$(whoami)" ' 
    BEGIN {TOTAL = 0} 
    END {print "Total is " TOTAL} 
    { 
     if ($1 == USER) { 
      TOTAL += $2 
     } 
    } 
' 

AWK是这样的假设一个循环(如perl -n)和处理文件中的每一行编程语言。每个字段(通常由空白分隔)都被赋予一个$变量。首先是$1,第二个是$2

-v选项允许我定义一个变量AWK(在这种情况下USER)之前我运行AWK。

BEGIN行是我想在我运行我的awk脚本之前要做的事情。在这种情况下,初始化TOTAL为零。 (注意:因为未定义的变量自动赋值为零,所以这不是必须的)。 END行是我想要做的事情之后。在这种情况下,打印出我的总数。

因此,如果第一个字段($ 1)等于我的用户,我会将第二个字段(vsize)添加到我的总数中。

所有Awk程序被{...}包围,它们通常围绕它们单引号以防止$1等的壳内插。

+1

为了便于阅读,我更喜欢把'END'块放在......末尾。此外,不需要if语句 - 将条件放在主块花括号之外:'$ 1 == USER {TOTAL + = $ 2}' –

+1

+1,但请注意,BEGIN没有真正的需要。只需在END中使用'TOTAL + 0'来确保打印'0'而不是空字符串。变量被自动置为0. –

+0

我喜欢把BEGIN块和END块放在开头,这样人们就会看到它们。否则,人们会想念他们。是的,这是比需要更多的代码。但是,我想强调语言部分。 Awk是一种具有许多功能的编程语言。我可以用一行代码简化整个事情:'ps -u $(whoami)--no-header -o vsz | awk'END {print“Total是”TOTAL} {TOTAL + = $ 1}“,但我想再次强调Awk语言。 –

0

Ignacio的答案很好,但流程替换不是可移植的。并有一个更简单的解决方案。您需要回响在同一子shell总在它的计算方法:

... | { while read line; do ...; done; echo total: $total; } 
相关问题