LoginSignup
3
3

More than 5 years have passed since last update.

linux / c > link > シェルコマンドの実行結果をCプログラム内で取得する > popen()を使う方法を教えていただいた

Last updated at Posted at 2016-10-21
動作環境
CentOS 6.5

シェルコマンド(例: who)の文字列をexecl()などで実行して、Cプログラム内で結果を取得できるか疑問に思った。

参考
http://stackoverflow.com/questions/1776632/how-to-catch-the-ouput-from-a-execl-command

試してみた。
上記のリンク先のコードは1行だけの取得だが、以下では複数行を取得するようにしている。

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

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");

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

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

  return 0;
}

int main()
{
  cmd_quem(); 
}
結果
% ./a.out        
Data from who command: wrf      tty1         2016-10-21 01:26 (:0)
Data from who command: wrf      pts/0        2016-10-21 01:29 (:0.0)
Data from who command: wrf      pts/1        2016-10-21 01:32 (:0.0)
whoの結果
% who
wrf      tty1         2016-10-21 01:26 (:0)
wrf      pts/0        2016-10-21 01:29 (:0.0)
wrf      pts/1        2016-10-21 01:32 (:0.0)

コードが非常に長くなってしまうのが難点である。

popen()を使う改良版

(追記 2016/10/21)

@hurou927 さんにpopen()を使う方法を教えていただいた。

こちらの方がずっとシンプルで見やすい。

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3