为什么我的代码不能正常工作?

时间:2012-05-30 21:23:02

标签: bash

我有这段代码:

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中)具有正确的价值。

5 个答案:

答案 0 :(得分:3)

答案 1 :(得分: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之前定义一个awk变量(在本例中为USER)。

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

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

所有Awk程序都被{...}包围,并且它们通常在它们周围有单引号以防止$1等的shell插值。

答案 2 :(得分: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"

答案 3 :(得分:0)

让我们减少您需要的额外流程数量:)

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

首先,使用ps的各种选项生成所需的进程大小列表,以千字节为单位。使用bash for循环遍历该列表,在使用'integer'属性声明的参数中保持运行总计以便于算术运算。所需的金额现在在total,随时可用于您需要的任何用途。总和包括ps进程本身使用的内存。

使用while(Dennis的建议)并避免过程替换(William的建议):

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

(对于真正的单行,这是我从https://stackoverflow.com/a/453290/1126841借来的dc命令:

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

此总和包括psdc命令本身使用的内存。)

答案 4 :(得分:0)

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

... | { while read line; do ...; done; echo total: $total; }