1

我试图找出子进程是否正在等待用户输入(不解析其输出)。是否有可能在 Unix 上的 C 中确定管道的读取端当前是否有 read() 调用阻塞?

问题是,我无法控制子进程中执行的程序。他们打印出我通常希望重定向到 /dev/null 的各种冗长的垃圾。偶尔会提示用户一些东西。(提示没有可靠的格式。)所以我的想法是:

  • 在一个循环中:
    • 排空孩子的标准输出,将其附加到临时缓冲区。
    • 检查(不知道如何)孩子是否要求用户输入,在这种情况下,缓冲区将打印到标准输出。
  • 当孩子退出时,扔掉缓冲区。
4

6 回答 6

1

问题是,我无法控制子进程中执行的程序。他们打印出我通常希望重定向到 /dev/null 的各种冗长的垃圾。偶尔会提示用户一些东西。(提示没有可靠的格式。)所以我的想法是:

  • 在一个循环中:
    • 排空孩子的标准输出,将其附加到临时缓冲区。
    • 检查(不知道如何)孩子是否要求用户输入,在这种情况下,缓冲区将打印到标准输出。
  • 当孩子退出时,扔掉缓冲区。
于 2009-01-16T18:37:47.157 回答
1

这听起来好像您正在尝试监督 dpkg,有时某些安装后脚本会询问管理员它是否会覆盖某些配置文件。

无论如何,您可能想看看 strace 是如何工作的:

strace -f -etrace=read your.program

当然,您需要跟踪哪些 fd 是您编写的管道,但无论如何您可能只需要标准输入。

于 2009-01-20T14:14:37.787 回答
1

您有以下选择:

  • 如果您知道孩子需要某些输入(例如将读取命令的 shell),只需写入管道
  • 如果您假设孩子通常不会阅读任何内容,但有时可能会这样做,您可能需要在 shell 中进行作业控制(使用终端与孩子进行通信,使用终端上的进程组和 TIOCSPGRP ioctl 来获取孩子到后台;当孩子试图从终端读取时,它会得到 SIGTTIN,你可以等待())。这就是 bash 处理诸如“ (sleep 10; read a;)&”之类的事情的方式
  • 如果你不知道要写什么,或者你有更多的可能性,你将不得不解析输出
于 2009-01-18T16:26:17.523 回答
0

您通常只需写入管道,或使用 select 或 poll。如果您需要握手机制,您可以通过各种方式在带外执行此操作,或者提出带内协议。

我不知道是否有内置方法可以知道另一端的阅读器是否阻塞。为什么你需要知道这个?

于 2009-01-16T12:51:30.677 回答
0

我不认为这是真的:例如,就在读取器端调用 read() 之前,管道会有一个实际上没有读取的读取器。

于 2009-01-16T11:22:59.957 回答
-1

如果我没记错的话,你不能有一个没有阅读器的管道,这意味着你一直有一个 read(2) 或一个 select(2) 系统挂起。

于 2009-01-16T11:19:08.810 回答