Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
从C程序中执行程序_C_Linux - Fatal编程技术网

从C程序中执行程序

从C程序中执行程序,c,linux,C,Linux,如何从C程序中运行另一个程序?我需要能够将数据写入已启动程序的STDIN(可能从它的STDOUT读取) 我不确定这是否是一个标准的C函数。我需要在Linux下工作的解决方案。您想使用popen。它提供了一个单向管道,您可以使用它访问程序的标准输入和标准输出 popen是现代unix和类unix操作系统的标准,Linux就是其中之一:-) 类型 在终端上阅读更多关于它的信息 编辑 popen是生成单向管道还是双向管道取决于实现。在和中,popen生成单向管道,这些管道是只读或只读的。打开,pope

如何从
C
程序中运行另一个程序?我需要能够将数据写入已启动程序的
STDIN
(可能从它的
STDOUT
读取)


我不确定这是否是一个标准的C函数。我需要在Linux下工作的解决方案。

您想使用
popen
。它提供了一个单向管道,您可以使用它访问程序的标准输入和标准输出

popen是现代unix和类unix操作系统的标准,Linux就是其中之一:-)

类型

在终端上阅读更多关于它的信息

编辑

popen
是生成单向管道还是双向管道取决于实现。在和中,
popen
生成单向管道,这些管道是只读或只读的。打开,popen产生双向管道。

我想你可以使用

freopen

为了这个

  • 使用
    pipe(…)
    创建两个管道,一个用于
    stdin
    ,一个用于
    stdout
  • fork(…)
  • 在子进程中(其中
    fork(…)
    返回0)
    dup(…)
    stdin
    /
    stdout
    的管道
  • exec[v][e]
    子进程中要启动的程序文件
  • 在父进程(其中
    fork
    返回子进程的PID)中,执行一个循环,从子进程的
    标准输出(
    选择(…)
    轮询(…)
    读取(…)
    )读取缓冲区,直到 子项终止(
    waitpid(…)
  • 最终,如果孩子需要,在
    stdin
    上为其提供输入
  • 完成后
    关闭(…)
    管道

  • 您可以使用系统调用read

    进行简单的单向通信,popen()是一个不错的解决方案。不过,双向通信是没有用的

    在国际海事组织,伊姆豪尔赫(豪尔赫·费雷拉)给出了双向通信的大部分答案(80%?),但忽略了一些关键细节

  • 父进程关闭用于向子进程发送消息的管道的读取端是至关重要的
  • 子进程必须关闭用于向子进程发送消息的管道的写入端
  • 父进程必须关闭用于向父进程发送消息的管道的写入端
  • 子进程关闭用于向父进程发送消息的管道的读取端至关重要
  • 如果不关闭管道的未使用端,则当其中一个程序终止时,将无法获得合理的行为;例如,子级可能正在读取其标准输入,但除非子级中管道的写入端关闭,否则它将永远不会获得EOF(读取零字节),因为它仍然打开管道,并且系统认为它可能会在某个时候开始写入该管道,即使它当前挂起,等待从中读取内容

    书写过程应考虑是否处理在没有读取过程的管道上写入的SIGPUTE信号。


    您必须了解管道容量(取决于平台,可能只有4KB),并设计程序以避免死锁。

    不久前,我为其他人编写了一些示例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);
    }
    
    #包括
    #包括
    #包括
    无效错误(字符*s);
    char*data=“一些输入数据\n”;
    main()
    {
    int in[2],out[2],n,pid;
    char-buf[255];
    /*在管道中,xx[0]用于读取,xx[1]用于写入*/
    如果(管道(in)<0)错误(“管道in”);
    如果(管道(输出)<0)错误(“管道输出”);
    如果((pid=fork())==0){
    /*这是子进程*/
    /*关闭标准输入、标准输出、标准输出*/
    关闭(0);
    关闭(1);
    关闭(2);
    /*制造我们的管道,我们的新标准,标准和标准*/
    dup2(in[0],0);
    dup2(out[1],1);
    dup2(out[1],2);
    /*关闭父级将使用的管道的其他端点,因为如果
    *我们在子级中保留这些打开状态,子级/父级将不会获得EOF
    *当父/子对象关闭其管道末端时。
    */
    关闭(在[1]中);
    关闭(关闭[0]);
    /*使用hextump二进制文件重写子进程*/
    execl(“/usr/bin/hextump”、“hextump”、“-C”、(char*)NULL);
    错误(“无法执行hextump”);
    }
    printf(“将'hextump-C'派生为pid%d\n'处的子进程”,pid);
    /*这是父进程*/
    /*关闭子对象用于读取/写入so的管道端点
    *当我们关闭其他设备时,EOF将正确传输。
    */
    关闭(在[0]中);
    关闭(关闭[1]);
    printf(“%s”,buf);
    出口(0);
    }
    无效错误(字符*s)
    {
    佩罗尔(s);
    出口(1);
    }
    
    请注意,它是stdin或stdout,而不是同时使用两者。在现代实现中,它是stdin和stdout。管道可以是双向的,尽管传统上它是单向的。Ubuntu 9.04上的“man popen”说,“因为管道定义为单向的,所以类型参数可能只指定读取或写入,而不是两者都指定”。@freespace哪些实现是单向的?你能引用他们的文档吗?@n.m.在OS X
    popen
    上允许单向管道:。对于*BSD,情况似乎也是如此。
    #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);
    }