【问题标题】:Using variables in unix command line commands在 unix 命令行命令中使用变量
【发布时间】:2022-02-27 17:46:51
【问题描述】:

我正在尝试使用找到的步骤here 计算处理器的 CPU 负载。我设法做到了:

cat /proc/stat | head -n 1 | awk '{print ($5+$6, $2+$3+$4+$7+$8+$9)}' | awk '{print($1,$1+$2)}'

这给了我我需要的价值观。但是,我需要在一秒钟后计算相同的值,然后使用这两个结果来计算最终负载。这意味着,我需要做这样的事情:

cat /proc/stat | calculate something | awk '{print($1,$1+$2)}' ; sleep for a second; calculate again; use both of the results

有没有办法让我在第一次 awk 调用中保存变量 $1 和 $1+$2,以便我以后可以使用它们?我不能使用 bash 脚本,它需要在命令行中完成。

【问题讨论】:

  • bash script, it needs to be done in a command line 命令行是bash,也一样。 hat I need to do something 那就这样做吧。 a=$(....); sleep 1; b=$(...); echo use $a and $b.
  • 您能否扩展您的评论:it needs to be done in a command line.?每次您需要执行此操作时...您要在命令提示符下手动键入吗?把它放在一个可以重复执行的脚本中不是更有意义吗(不需要做所有的输入,或者通过手动输入引入语法/逻辑错误)?甚至将逻辑放入一个函数(一种“脚本”;参见 EdMorton 的回答)也会有用

标签: shell unix awk


【解决方案1】:

您无需为现有命令拼凑对管道中工具的单独调用。这个:

cat /proc/stat | head -n 1 | awk '{print ($5+$6, $2+$3+$4+$7+$8+$9)}' | awk '{print($1,$1+$2)}'

可以改写成这样:

awk 'NR==1{x=$5+$6; print x, x+$2+$3+$4+$7+$8+$9; exit}' /proc/stat

听起来您可能想要做的是:

foo() { awk 'NR==1{x=$5+$6; print x, x+$2+$3+$4+$7+$8+$9; exit}' /proc/stat; }
{ foo; sleep 1; foo; } | awk 'NR==1{ p1=$1; p2=$2; next } { use p1, $1, p2, and $2 }'

如果您无法根据这些信息做任何您想做的事情,那么请编辑您的问题以提供更清晰的要求和一些简洁、可测试、真正具有代表性的示例输入/输出。

【讨论】:

    【解决方案2】:

    一个简单的解决方案是首先创建完整的输入,然后使用awk 处理它。我们首先定义cpuLoadbash函数以1秒的间隔捕获两次CPU负载:

    $ cpuLoad () {
        head -n 1 /proc/stat
        sleep 1
        head -n 1 /proc/stat
      }
    $ cpuLoad
    cpu  8481582 17390 3183770 873720681 403491 0 708461 0 0 0
    cpu  8481582 17390 3183774 873721078 403491 0 708461 0 0 0
    

    然后我们可以提供一个awk 脚本,该脚本实现了您引用的已接受答案的确切算法:

    $ cpuLoad | awk '{
        Idle = $5+$6
        NonIdle = $2+$3+$4+$7+$8+$9
        Total = Idle + NonIdle
        totald = Total - PrevTotal
        idled = Idle - PrevIdle
        PrevTotal = Total
        PrevIdle = Idle
      }
      END {
        CPU_Percentage = 100.0 * (totald - idled) / totald
        print CPU_Percentage
      }'
    4.987531
    

    但我们可以简化很多:

    $ cpuLoad | awk '{
        totald = $2+$3+$4+$5+$6+$7+$8+$9 - totald
        idled = $5+$6 - idled
      }
      END {
        print 100.0 * (totald - idled) / totald
      }'
    0.501253
    

    最后,我们可以将所有这些封装在bash 函数中:

    $ cpuLoad () {
        { head -n 1 /proc/stat; sleep 1; head -n 1 /proc/stat; } |
        awk '{t = $2+$3+$4+$5+$6+$7+$8+$9 - t; i = $5+$6 - i}
          END {print 100.0 * (t - i) / t}'
      }
    $ cpuLoad
    0.750000
    

    【讨论】:

    • 这很有意义。我太专注于帮助 OP 实施他们要求的解决方案,而没有考虑是否有更好的解决方案。
    猜你喜欢
    • 2017-02-09
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 2016-09-19
    • 2019-03-04
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多