【问题标题】:C++ Linux Interact Another Program stdin / stdoutC++ Linux 交互另一个程序标准输入/标准输出
【发布时间】:2017-02-03 06:30:20
【问题描述】:

我在 Linux 中有一个可执行文件,可以与 stdin/stdout 交互。我正在尝试用 C++ 编写一个程序,该程序可以交互地调用该程序,将命令发送到它的标准输入,并捕获它的标准输出。

我真的很困惑。我不想分叉我的程序(是吗?)。我确实希望我的程序能够启动“客户端”、发送数据、获取输出、发送更多数据、获取更多输出……然后关闭“客户端”。

附:是的,我确定以前有人问过这个问题,但我花了几个小时真的摸不着头脑——可能没有使用正确的关键字。

【问题讨论】:

  • 你想用低级系统调用来写这个还是你可以使用库?一种选择是使用libexpect
  • @MarkPlotnick 这是一个个人项目,所以任何能让这件事变得更容易的方法都是可行的。
  • @MarkPlotnick 实际上是的,这真的很好用!我已经切换到使用 tcl8.6 中的 exp_popen() 调用。这将打开一个进程并返回一个文件句柄,我可以像任何其他文件一样读取/写入它。

标签: c++ linux shell interactive


【解决方案1】:

执行另一个程序的唯一方法是通过exec() 系统调用之一。这是唯一的方法。而且,如您所知,exec()exec() 指定的程序替换正在执行的程序。发出exec() 的进程将不再存在,它的PID 现在被新程序使用。

因此从逻辑上讲,除非您希望您的程序被其他可执行文件替换,否则您的程序必须fork(),并且子进程使用exec() 来执行新的可执行文件。这是启动新进程并继续运行原始进程的传统方式。为此需要fork()

你描述的情况是相当典型的,按数字绘制的情况,已经被无数次做了:

  1. 使用 pipe() 创建两个管道,一个用于管道标准输入,一个用于管道标准输出。

  2. 使用 fork()。子进程dup2()s stdin 管道的读取端为0,stdout 管道的写入端为1,关闭每个原始管道的两端,exec()s 新进程。

  3. 父进程关闭标准输入管道的读端、标准输出管道的写端,然后使用标准输入管道的写端和标准输出管道的读端继续与子进程交互.

【讨论】:

  • 很好的解释。在我自己的研究中,你填补了我脑海中浮现的部分。顺便说一句,这似乎是一个可怕的接口,很久以前就会被替换和抽象掉。不过感谢您的帮助!
  • @CircuitGuy Windows 在这方面做得更好,信不信由你。 (您调用 CreateProcess 并简单地将您希望子进程用于标准输入和标准输出的句柄传递给它)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
相关资源
最近更新 更多