C,将AWK语法作为参数传递给execl

时间:2010-04-17 21:20:59

标签: c linux awk exec

我想从C程序运行以下命令来读取系统的CPU和内存使用情况:

ps aux|awk 'NR > 0 { cpu +=$3; ram+=$4 }; END {print cpu,ram}'

我试图将它传递给execl命令,然后读取它的输出:

execl("/bin/ps", "/bin/ps", "aux|awk", "'NR > 0 { cpu +=$3; ram+=$4 }; END {print cpu,ram}'",(char *) 0);

但是在终端中我收到以下错误:

  

错误:不支持的选项(BSD语法)

我想知道如何正确地将awk作为参数传递给execl

3 个答案:

答案 0 :(得分:1)

你不能这样做。

问题是你想要执行几个命令。 execl用于执行单个命令。您拥有的语句是使用shell语法(特别是|)

您可以更好地将它组合在一个字符串中并使用system(3)调用。

答案 1 :(得分:1)

您可以在C中进行过滤和求和,而不是运行awk并解析awk的输出,这通常可以很快变得更加方便。 (这与你在这里的确切命令大致相同。)

#include <errno.h>
#include <stdio.h>

void ps_cpumem(FILE* f, double* cpu_total, double* mem_total) {
  for (;;) {
    char buf[2000];
    if (!fgets(buf, sizeof buf, f)) {
      return;
    }
    double cpu, mem;
    if (sscanf(buf, "%*s %*s %lf %lf", &cpu, &mem) == 2) {
      *cpu_total += cpu;
      *mem_total += mem;
    }
  }
}

int main() {
  errno = 0;
  FILE* ps = popen("ps aux", "r");
  if (!ps) {
    if (errno == 0) puts("popen: memory allocation failed");
    else perror("popen");
    return 1;
  }
  double cpu = 0, mem = 0;
  ps_cpumem(ps, &cpu, &mem);
  int rc = pclose(ps);
  if (rc == -1) return 1;
  printf("%%cpu: %5.1f\n" "%%mem: %5.1f\n", cpu, mem);
  return 0;
}

但是,您可以通过popen运行完整命令,因为它执行shell:

FILE* output = popen("ps aux | awk 'NR > 0 { cpu +=$3; ram+=$4 }; END {print cpu,ram}'", "r");
// read from output to do with as you like

答案 2 :(得分:1)

正如所建议的那样,popen()是您想要捕获输出以便在程序中随后使用的内容。但是,如果您真的想要执行exec操作,可以使用shell通过execl()进行出价:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    printf("%s: execl returned unexpectedly: %d", argv[0],
            execl("/bin/sh", "/bin/sh", "-c",
            "ps aux | awk 'NR >0 { cpu += $3; ram+=$4}; END {print cpu, ram}'",
            NULL));
    exit(1);
}