简体   繁体   English

如何将awk变量传递给bash命令

[英]How to pass an awk variable to a bash command

How can I pass an awk variable to a bash command run within awk ? 如何将awk变量传递给在awk运行的bash命令?

I'm using awk to calculate a running sum of threads for each of a certain process, but then I want to use each pid to access the /proc/$pid filesystem. 我正在使用awk计算每个特定进程的线程运行总和,但后来我想使用每个pid来访问/proc/$pid文件系统。

The line marked broken below is incorrect, because $pid is non-existent. 下面标记为断开的行不正确,因为$pid不存在。

How can I export the awk variable pid to the shell command I get awk to run? 如何将awk变量pid导出到shell命令我运行awk

(Line breaks added for readability) (为了便于阅读,添加了换行符)

$ ps -ALf | grep $PROC | grep -v grep | \         # get each pid
    awk '{threads[$2]+=1} END \                   # count num threads per pid
         { \
           for (pid in threads) \
              "cat /proc/$pid/cwd"|getline cwd; \ # get 'cwd' (**broken**)
               print cwd ": " threads[pid] \      # display 'cwd' and num threads
         }'

You cannot cat /proc/$pid/cwd it is a symlink to a directory. 你不能cat /proc/$pid/cwd它是一个目录的符号链接。 One way to resolve symlinks is with readlink from coreutils. 解决符号链接的一种方法是使用coreutils的readlink

Here is a working example using bits from TrueY and Barmer : 这是一个使用TrueYBarmer中的位的工作示例:

ps -C $PROC | 
awk '{ t[$1] } END { for(p in t) { "readlink -f /proc/" p "/cwd" | getline c; print c } }'

A couple of things to notice: 有几点需要注意:

  • Pipe doubles as a line continuation character. 管道兼作线延续字符。
  • It is enough to refer to an array entry to create it ( t[$1] ). 引用数组条目来创建它( t[$1] )就足够了。

awk doesn't do variable interpolation inside strings, you just concatenate the variable with the strings (just like you do in the print statement). awk不在字符串中进行变量插值,只需将变量与字符串连接起来(就像在print语句中一样)。

awk '{threads[$2]+=1} END                    # count num threads per pid
     { 
       for (pid in threads) 
          ("cat /proc/" pid "/cwd")|getline cwd;  # get 'cwd' (**broken**)
           print cwd ": " threads[pid]       # display 'cwd' and num threads
     }'

You also don't need all those backslashes. 你也不需要所有那些反斜杠。 Newlines inside a quoted string don't need to be escaped (and some of them weren't even before newlines, there were comments after them). 引用字符串中的换行符不需要进行转义(其中一些甚至不在换行符之前,后面有注释)。

You can do the whole lot in without any grep s link this: 您可以在而无需任何grep s链接:

% ps -ALf | awk -v proc="${PROC}" '
$0 ~ proc && !/awk/ {
    threads[$2] += 1
}
END {
    for (pid in threads) {
        "readlink /proc/" pid "/cwd" | getline dir
        printf "%d: %d %s\n", pid,  threads[pid], dir
        dir=""
    }
}'

A few things worth noting: 一些值得注意的事情:

  • -v proc="${PROC}" assigns the environment variable ${PROC} to an awk variable, proc -v proc="${PROC}"将环境变量${PROC}分配给awk变量proc
  • "readlink /proc/" pid "/cwd" concatenates the three strings. "readlink /proc/" pid "/cwd"连接三个字符串。 There's no need for any concatenation operator in awk . awk不需要任何连接运算符。
  • dir="" resets the dir variable, in case the symlink is not readable the next time around the loop. dir=""重置dir变量,以防下次循环时符号链接不可读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM