在 C++ 中使用 popen 连续写入子进程

Posted

技术标签:

【中文标题】在 C++ 中使用 popen 连续写入子进程【英文标题】:Continuously write to subprocess using popen in C++ 【发布时间】:2015-05-25 02:40:09 【问题描述】:

我需要使用 popen 打开一个子进程,该进程将不断要求用户输入...主进程需要通过管道发送该数据。

这是我的第一次尝试:

FILE *in;
char buff[1024];

if(!(in = popen("cd FIX/fix2/src; java -cp .:./* com.fix.bot", "w")))
    return 1;


while(1)
    char buffer[] =  'x' ;
    fwrite(buffer, sizeof(char), sizeof(buffer), in);

    cout << "Wrote!" << endl;
    usleep(1000000);

但是数据没有发送!我需要用 pclose() 关闭管道,以便将数据写入进程。如何确保写入数据而不必每次都关闭管道?

【问题讨论】:

您的应用是否可能正在寻找以 \n 结尾的输入?因为你现在没有发送 LF... 别忘了检查fwrite() 的结果,我认为它并不能保证写出你所要求的一切。通常可以,但您需要验证。 【参考方案1】:

您需要调用fflush(in) 以确保缓冲数据实际写入流中。

还要检查命令中的java -cp .:./* 是否没有扩展到无效的类路径。如果当前目录中有多个文件,而不是实际的类路径条目,我认为最终会扩展到多个参数。

【讨论】:

它仍然没有刷新...即使使用 fflush(),我仍然需要关闭管道。可能是什么问题? 我更新了答案,我认为也可能是类路径设置错误。试试echo java -cp .:./* 看看它是否合法。 我会确保检查命令以打开 java 进程......但到目前为止它似乎工作正常。当我关闭它时,数据被写入管道,Java 进程会做出相应的响应。但我需要确保数据已刷新.... 手册页中的另一条注释:“由于打开用于读取的命令的标准输入与调用 popen() 的进程共享其查找偏移量,如果原始进程已完成缓冲读取,则命令的输入位置可能与预期不同。同样,打开写入的命令的输出可能会与原始进程的输出混合。后者可以通过在 popen() 之前调用 fflush(3) 来避免。" @LuisCruz:那么你的问题在于读者,而不是作者。 fflush 肯定会将字节写入管道。关闭管道唯一要做的就是发送 EOF。您需要展示您的阅读端源代码并将其更改为 Java 问题。【参考方案2】:

这对我有用:

#include <stdio.h>
#include <unistd.h>
#include <iostream>

int main(int argc, char ** argv) 
   FILE *in;
   char buff[1024];

   if(!(in = popen("./2.sh", "w")))
       return 1;
   

   while(1) 
      char buffer[] = "xx\n";
      fwrite(buffer, sizeof(char), sizeof(buffer), in);
      fflush(in);
      std::cout << "Wrote!" << std::endl;
      usleep(1000000);
   

2.sh 在哪里:

#!/bin/sh

read INP
echo 'read: ' $INP

所以我真的怀疑问题丢失了\n。

【讨论】:

以上是关于在 C++ 中使用 popen 连续写入子进程的主要内容,如果未能解决你的问题,请参考以下文章

创建一个不是创建进程子进程的新进程

Linux学习-进程管理

Shell脚本入门 07:进程与信号

Shell脚本入门 07:进程与信号

在 Swift 3 中包含字典的 Firebase 进程子快照

golang 热重启