動作環境
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()を使う方法を教えていただいた。
こちらの方がずっとシンプルで見やすい。