GNU/Linux >> Linux の 問題 >  >> Linux

C プログラム内からプログラムを実行する

popen を使用したい .プログラムの stdin と stdout にアクセスできる単方向パイプを提供します。

popen は最新の UNIX および UNIX ライクな OS の標準であり、Linux もその 1 つです :-)

タイプ

man popen

端末で詳細を確認してください。

編集

popenかどうか 実装に応じて、単方向または双方向のパイプを生成します。 Linux および OpenBSD では、popen 読み取り専用または書き込み専用の一方向パイプを生成します。 OS X、FreeBSD、および NetBSD popen の場合 双方向パイプを生成します。


しばらく前に、これを行う方法を示す C コードの例を他の誰かのために書きました。ここにあります:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

void error(char *s);
char *data = "Some input data\n";

main()
{
  int in[2], out[2], n, pid;
  char buf[255];

  /* In a pipe, xx[0] is for reading, xx[1] is for writing */
  if (pipe(in) < 0) error("pipe in");
  if (pipe(out) < 0) error("pipe out");

  if ((pid=fork()) == 0) {
    /* This is the child process */

    /* Close stdin, stdout, stderr */
    close(0);
    close(1);
    close(2);
    /* make our pipes, our new stdin,stdout and stderr */
    dup2(in[0],0);
    dup2(out[1],1);
    dup2(out[1],2);

    /* Close the other ends of the pipes that the parent will use, because if
     * we leave these open in the child, the child/parent will not get an EOF
     * when the parent/child closes their end of the pipe.
     */
    close(in[1]);
    close(out[0]);

    /* Over-write the child process with the hexdump binary */
    execl("/usr/bin/hexdump", "hexdump", "-C", (char *)NULL);
    error("Could not exec hexdump");
  }

  printf("Spawned 'hexdump -C' as a child process at pid %d\n", pid);

  /* This is the parent process */
  /* Close the pipe ends that the child uses to read from / write to so
   * the when we close the others, an EOF will be transmitted properly.
   */
  close(in[0]);
  close(out[1]);

  printf("<- %s", data);
  /* Write some data to the childs input */
  write(in[1], data, strlen(data));

  /* Because of the small amount of data, the child may block unless we
   * close it's input stream. This sends an EOF to the child on it's
   * stdin.
   */
  close(in[1]);

  /* Read back any output */
  n = read(out[0], buf, 250);
  buf[n] = 0;
  printf("-> %s",buf);
  exit(0);
}

void error(char *s)
{
  perror(s);
  exit(1);
}

<オール>
  • pipe(...) で 2 つのパイプを作成します 、stdin に 1 つ 、stdout に 1 つ .
  • fork(...)
  • 子プロセス (fork(...) があるプロセス) 0 を返します) dup (...) stdin へのパイプ /stdout .
  • exec[v][e] 子プロセスで起動されるプログラム ファイル。
  • 親プロセス (fork があるプロセス) ) 子の PID を返します) 子の stdout から読み取るループを実行します (select(...) または poll(...)read(...) ) をバッファに入れ、子が終了するまで (waitpid(...) )。
  • 最終的に stdin で子に入力を提供します
  • 完了したら close(...)

  • Linux
    1. プログラムをどこからでも実行可能にする方法は?

    2. Bashスクリプト内からフルパスを取得しますか?

    3. Sigintが子プロセスに到達するのを防ぎますか?

    1. CHILD PROCESSから戻り値を取得するには?

    2. 内部からC++ Linuxプログラムのフルパスを見つける方法は?

    3. PythonGDB (GDB 7.1) で gdb.execute から出力を取得するには?

    1. Linux カーネル モジュール内からユーザー空間関数を呼び出す

    2. 親プロセスから子プロセスを取得する方法

    3. コマンドLinuxラインからのmatlab実行スクリプト