【问题标题】:Shell script to cut /proc/softirqs用于剪切 /proc/softirqs 的 Shell 脚本
【发布时间】:2016-10-22 09:50:12
【问题描述】:

以下是“cat /proc/softirqs”的输出:

                    CPU0       CPU1       CPU2       CPU3
          HI:         24         13          7         54
       TIMER:  344095632  253285150  121234786  108207697
      NET_TX:    2366955        319        695     316044
      NET_RX:   16337920   16030558  250497436  117201444
       BLOCK:      19631       2747       2353    5067051
BLOCK_IOPOLL:          0          0          0          0
     TASKLET:        298         93        157      20965
       SCHED:   74354472   28133393   30646119   26217748
     HRTIMER: 4123645358 2409060621 2466360502  401470590
         RCU:   26083738   17708780   15330534   16857905

我的另一台机器有 24 个 cpu 核心,输出很难阅读, 我喜欢输出只有 cpu0 , cpu2 , cpu4 , cpu6, .... 我知道可能会使用 cut 或 awk 来做到这一点, 但不知道如何使用它来获得输出列。

编辑:

awk -F" " '{printf("%10s\t%s\n", $2,$4) }'

会得到

      CPU1  CPU3
        24  7
 344095632  121234786
   2366955  695
  16337920  250497436
     19631  2353
         0  0
       298  157
  74354472  30646119
4123645358  2466360502
  26083738  15330534

不幸的是,CPU1 应该是 CPU0 ,CPU3 应该是 CPU2 , 第一行只有4列,我可以跳过第一行吗 在这个外壳里?!

编辑2:

watch -d "cat /proc/softirqs | awk -F" " '{printf("%10s\t%s\n",$2,$4)}' "

遇到如下错误:

Every 2.0s: cat /proc/softirqs | awk -F  '{print    }' Tue Jun 21 10:23:22 2016

Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:          GNU long options: (standard)
        -f progfile             --file=progfile
        -F fs                   --field-separator=fs
        -v var=val              --assign=var=val
Short options:          GNU long options: (extensions)
        -b                      --characters-as-bytes
        -c                      --traditional
        -C                      --copyright
        -d[file]                --dump-variables[=file]
        -e 'program-text'   --source='program-text'
        -E file                 --exec=file
        -g                      --gen-pot
        -h                      --help
        -L [fatal]              --lint[=fatal]
        -n                      --non-decimal-data
        -N                      --use-lc-numeric
        -O                      --optimize
        -p[file]                --profile[=file]
        -P                      --posix
        -r                      --re-interval
        -S                      --sandbox
        -t                      --lint-old
        -V                      --version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
        gawk '{ sum += $1 }; END { print sum }' file
        gawk -F: '{ print $1 }' /etc/passwd

我还应该尝试什么?!

编辑3:

最终可行的外壳是这样的:

# define function encapsulating code; this prevents any need for extra layers of quoting
# or escaping.
run() {
    awk  'NR>1{printf("%20s\t%10s\t%s\n",$1,$2,$4)}' </proc/softirqs|egrep 'TIMER|RX'
}

# export function
export -f run

# run function in subshell of watch, ensuring that that shell is bash
# (other shells may not honor exported functions)
watch -d  "bash -c run"

【问题讨论】:

  • 如果你想转义一串shell代码以将它传递给watchprintf %q是你的朋友——或者只是把它放在一个脚本中; watch——它在每次刷新时执行一个新的sh -c——效率非常低,以至于你不会因为一次额外的 shell 调用而损失太多。
  • 也就是说,问如何为watch 逃避事情应该是它自己的问题,而不是融入这个问题;可以说,您提出的问题过于宽泛,无法适应网站规则,因为它现在包含两个完全不同的问题,并且答案需要跨越这两个问题才能完全响应。
  • ...或者,如果您有自己喜欢的代码并且只想知道如何从watch 运行它,这也是可以接受的;它试图在一个过于宽泛的问题中获取格式化代码并从watch 运行它。

标签: shell awk cut


【解决方案1】:

将代码与watch 的子进程通信以避免转义错误的一种简单方法是使用导出函数:

# define function encapsulating code; this prevents any need for extra layers of quoting
# or escaping.
run() {
  awk -F" " '{printf("%10s\t%s\n",$2,$4)}' </proc/softirqs
}

# export function
export -f run

# run function in subshell of watch, ensuring that that shell is bash
# (other shells may not honor exported functions)
watch "bash -c run"

为了避免对导出函数的依赖,还可以使用declare -fevalable 形式检索函数的源代码,并使用printf %q 对其进行转义,以使其在watch 调用的外壳处理后继续存在:

run() {
  awk -F" " '{printf("%10s\t%s\n",$2,$4)}' </proc/softirqs
}
printf -v run_str '%q' "$(declare -f run); run"
watch "bash -c $run_str"

【讨论】:

    【解决方案2】:

    要跳过第一行,请执行以下操作:

    awk -F" " 'NR>1{printf("%10s\t%s\n", $2,$4) }'
    

    你为什么需要-F" ",对我来说是个谜。你也可以这样写:

    awk 'NR>1{printf("%10s\t%s\n", $2,$4) }'
    

    (至于watch部分,请参见其他答案。)

    【讨论】:

    • 确实不行。去掉了手表部分。没有手表,它可以工作。
    • 是的。这就是为什么我仍然认为如何格式化以及如何使其在watch 中工作应该是两个完全独立的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 2015-03-16
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多