开发者

C, pass AWK syntax as argument to execl

开发者 https://www.devze.com 2022-12-27 11:50 出处:网络
I want to run the following command from a C program to read the system\'s CPU and mem开发者_Python百科ory use:

I want to run the following command from a C program to read the system's CPU and mem开发者_Python百科ory use:

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

I am trying to pass it to the execl command and after that read its output:

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

But in the terminal I am getting the following error:

ERROR: Unsupported option (BSD syntax)

I would like to know how to properly pass awk as argument to execl?


You can't do this here this way.

The problem is that you want to execute several commands. execl is for executing a single command. The statement you have is using shell syntax (notably the | )

You will have better luck combining it all up in a single string and using the system(3) call.


Instead of running awk and parsing awk's output, you can do the filtering and summation in C, which often can quickly become much more convenient. (It's about the same for the exact command you have here.)

#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;
}

However, you can run the full command through popen, as it executes a 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


As Will suggested, popen() is what you want for capturing output for subsequent use inside your program. However, if you truly are wanting to do an exec operation, you can use the shell to do your bidding via 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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号