Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从execl命令捕获输出_C_Linux_Subprocess - Fatal编程技术网

如何从execl命令捕获输出

如何从execl命令捕获输出,c,linux,subprocess,C,Linux,Subprocess,我正在使用execl函数从C运行Linux进程。当我这样做时,例如: int cmd_quem() { int result; result = fork(); if(result < 0) { exit(-1); } if (result == 0) { execl("/usr/bin/who", "who", NULL); sleep(4); //checking if father is being polite exit(

我正在使用
execl
函数从C运行Linux进程。当我这样做时,例如:

int cmd_quem() { 
  int result; 
  result = fork();
  if(result < 0) {
    exit(-1);
  }

  if (result == 0) {
    execl("/usr/bin/who", "who", NULL);
    sleep(4); //checking if father is being polite 
    exit(1); 
  } 
  else { 
    // father's time
    wait();
  }

  return 0;
}
这是who命令产生的一行。

exec()函数族从常规可执行文件创建新的进程映像。此文件是可执行对象文件或解释器脚本。成功调用exec()函数不会返回,因为调用进程在功能上被新进程替换

因此,exec()之后的任何代码都不会执行,除非失败


如果要捕获所需shell命令的输出。

首先,
execl
不会返回,除非出现类似未找到可执行文件的问题。睡眠(4)可能永远不会执行


至于重定向和获取输出,请查看。查找spawn\u background\u命令。

要执行此操作,您需要打开一个管道。然后用管道的写入端替换子管道的标准输出,并从父管道的读取端读取。与此代码的修改版本类似:

int cmd_quem(void) {
  int result;
  int pipefd[2];
  FILE *cmd_output;
  char buf[1024];
  int status;

  result = pipe(pipefd);
  if (result < 0) {
    perror("pipe");
    exit(-1);
  }

  result = fork();
  if(result < 0) {
    exit(-1);
  }

  if (result == 0) {
    dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */
    close(pipefd[0]);
    close(pipefd[1]);

    execl("/usr/bin/who", "who", NULL);
    _exit(1);
  }

  /* Parent process */
  close(pipefd[1]); /* Close writing end of pipe */

  cmd_output = fdopen(pipefd[0], "r");

  if (fgets(buf, sizeof buf, cmd_output)) {
    printf("Data from who command: %s\n", buf);
  } else {
    printf("No data received.\n");
  }

  wait(&status);
  printf("Child exit status = %d\n", status);

  return 0;
}
int cmd_quem(无效){
int结果;
int-pipefd[2];
文件*cmd_输出;
char-buf[1024];
智力状态;
结果=管道(pipefd);
如果(结果<0){
佩罗(“管道”);
出口(-1);
}
结果=fork();
如果(结果<0){
出口(-1);
}
如果(结果==0){
dup2(pipefd[1],标准输出文件号);/*标准输出的重复写入端*/
关闭(pipefd[0]);
关闭(pipefd[1]);
execl(“/usr/bin/who”,“who”,空);
_出口(1);
}
/*父进程*/
关闭(pipefd[1]);/*关闭管道的写入端*/
cmd_output=fdopen(pipefd[0],“r”);
if(fgets(buf、sizeof buf、cmd_输出)){
printf(“来自who命令的数据:%s\n”,buf);
}否则{
printf(“未收到任何数据。\n”);
}
等待(&状态);
printf(“子退出状态=%d\n”,状态);
返回0;
}

正确清理管道的工作做得很好-很少有人能做对。我做到了,但只有在我切换了
wait()
行并将其放在
fgets()
之前时,它才完全起作用,有什么解释吗?@mf\uz:那应该没什么区别-你在使用什么操作系统?@caf ubuntu 10.04LTS,但现在有了一些意义,父捕获缓冲区中的内容,即使只有几个字节,而如果我们等待()子完全完成,缓冲区将拥有所有内容,这是我的解释,如果你愿意,我可以发布我的调整版本piece@mf_:
fgets()
应该一直读到换行符或文件结尾,而不应该只读“几个字节”如果子对象没有输出换行符或退出。
int cmd_quem(void) {
  int result;
  int pipefd[2];
  FILE *cmd_output;
  char buf[1024];
  int status;

  result = pipe(pipefd);
  if (result < 0) {
    perror("pipe");
    exit(-1);
  }

  result = fork();
  if(result < 0) {
    exit(-1);
  }

  if (result == 0) {
    dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */
    close(pipefd[0]);
    close(pipefd[1]);

    execl("/usr/bin/who", "who", NULL);
    _exit(1);
  }

  /* Parent process */
  close(pipefd[1]); /* Close writing end of pipe */

  cmd_output = fdopen(pipefd[0], "r");

  if (fgets(buf, sizeof buf, cmd_output)) {
    printf("Data from who command: %s\n", buf);
  } else {
    printf("No data received.\n");
  }

  wait(&status);
  printf("Child exit status = %d\n", status);

  return 0;
}