GNU/Linux >> Znalost Linux >  >> Linux

Spusťte program z programu C

Chcete použít popen . Poskytuje vám jednosměrný kanál, pomocí kterého můžete přistupovat k stdin a stdout programu.

popen je standardem na moderních unixových a unixových OS, mezi které Linux patří :-)

Typ

man popen

v terminálu a přečtěte si o něm více.

UPRAVIT

Zda popen vyrábí jednosměrné nebo obousměrné potrubí závisí na implementaci. V Linuxu a OpenBSD, popen vytváří jednosměrné roury, které jsou pouze pro čtení nebo pouze pro zápis. V OS X, FreeBSD a NetBSD popen vyrábí obousměrné potrubí.


Před časem jsem napsal nějaký příklad kódu C pro někoho jiného, ​​​​který ukazuje, jak to udělat. Tady je pro vás:

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

  1. Vytvořte dva kanály pomocí pipe(...) , jeden pro stdin , jeden pro stdout .
  2. fork(...) proces.
  3. V podřízeném procesu (tomu, kde fork(...) vrátí 0) dup (...) potrubí na stdin /stdout .
  4. exec[v][e] soubor programu, který má být spuštěn v podřízeném procesu.
  5. V nadřazeném procesu (v tom, kde je fork ) vrátí PID dítěte) proveďte smyčku, která čte z stdout dítěte (select(...) nebo poll(...) , read(...) ) do vyrovnávací paměti, dokud se dítě neskončí (waitpid(...) ).
  6. Nakonec poskytněte dítěti vstup na stdin pokud nějaké očekává.
  7. Po dokončení close(...) potrubí.

Linux
  1. Odesíláte vstup na relaci obrazovky zvenčí?

  2. Získat úplnou cestu ze skriptu Bash?

  3. Zabránit Sigintu v dosahování dětských procesů?

  1. Spouštějte skripty Perl/PHP z příkazového řádku

  2. Jak extrahuji jeden kus bajtů ze souboru?

  3. Je bezpečné forkovat z vlákna?

  1. Volání funkce uživatelského prostoru z modulu jádra Linuxu

  2. matlab spustí skript z příkazové řádky linuxu

  3. Zrušte přetahování z nabitého programu