【问题标题】:Poking a character into a parent process's buffer将字符插入父进程的缓冲区
【发布时间】:2011-08-05 13:51:52
【问题描述】:

我正在尝试编写一个在后台运行的程序,该程序可以“键入”到父进程中,例如发出 shell 命令,就好像我自己在键盘上键入它们一样。我曾尝试使用ungetc() 执行此操作以推回STDIN

#include <stdio.h>

int main (int argc, char** argv) {
        ungetc('x', stdin);
        return 0;
}

我希望这样做:

$ gcc -o unget unget.c
$ ./unget&

我会在$ 提示符处留下x,就好像我刚刚输入它一样,但我什么也没得到。我是否因为进入后台而“迷失”了STDIN?谢谢!

【问题讨论】:

  • 您是在尝试完成 IPC 还是这是一个概念教授。
  • 这是为了“成为我”并在无人值守的情况下推动交互式会话。出于各种原因,我不能只在这种环境中使用 Expect。我还需要让终端空闲,以便我可以在必要时自己输入命令,因此是后台进程。
  • 例如我可能希望它每 x 分钟代表我运行一个命令,同时我继续在前台做一些事情,但它必须好像它来自我的 shell,这样 PPID 才能正确运行

标签: c shell terminal automated-tests


【解决方案1】:

您尝试做的事情根本行不通。 ungetc 对 stdio FILE 缓冲区进行操作,而不是底层打开文件描述,因此无法与其他进程共享。

您可以尝试在screen 中运行交互式会话,并使用屏幕的exec 命令通过将注入数据的进程重定向文件描述符。或者您可以使用伪 tty 设备自己实现类似的东西。

此外,从您的 cmets 来看,我认为您正在尝试做的事情是一个非常糟糕的主意。如果你不走运并且输入是在你交互输入的过程中出现的,那可能会造成灾难性的后果。例如成像自动命令是

command_foo my_important_file

现在假设你正在打字

rm -rf useless_crap

my_important_file 刚刚被删除。

【讨论】:

  • +1,pseudo-ttys 可能是解决方案。对于测试驱动程序,我会使用 expect 进行调查,而不是自己包装伪 tty。
  • 有一个非标准但方便的函数forkpty,它使得运行一个封装在伪tty 中的子进程变得非常容易。在没有它的系统上,您可以根据标准函数轻松实现它(尽管遗憾的是标准函数是非线程安全的,POSIX 并没有费心采用任何解决方案来解决这个问题......)。
  • 另请参阅我的另一个答案,了解一种完全不同的方法,实际上是安全的。
【解决方案2】:

否——ungetc 只是将字符“推”回程序自己的缓冲区,因此当同一程序读取的下一个字符将是传递给ungetc 的字符。将某些内容传输回父级需要完全不同的内容(例如,创建一些管道)。

【讨论】:

  • 管道无法满足 OP 的要求;只有伪 tty 设备,并且只有在相反的父/子关系或类似兄弟的关系下,才能做 OP 想要的。
  • @R.嗯,有点真实。如果父母非常想这样做,它可以使用dup2 将其标准输入连接到 dhild 的标准输出。我不知道你为什么要这样做,但我很高兴如果你这样做了。
  • 你不能像这样“连接”文件描述符并获得类似管道的行为;你需要一个管道(这会破坏交互行为)或一个伪终端。
【解决方案3】:

第二个答案与其说是对您的问题的书面回答,不如说是对您要解决的问题的回答。它比向你的 shell 发送击键要强大得多。

在 shell 中,使用trap 命令设置信号处理程序。例如:

trap "echo hello" USR2

USR2 替换为您想要使用的任何信号。然后运行一个定期向其父进程发送信号的子进程。

【讨论】:

  • 另请注意,您可以将孩子实现为 shell 脚本:( while : ; do sleep 30 ; kill -USR2 $PPID ; done ) &amp; child_pid=$!
【解决方案4】:

就在我的脑海中,也许您可​​以调整终端的管道,以便您孩子的 cout 对父母来说是 cin。在 bash 中它会是这样的:

exec 6>&1
exec 7<&0
exec 1>&7
exec 0<&6

然后,当您启动程序时,管道应该倒置。因此,您放入 cout 的所有内容都应该从您的父母那里以 cin 出现(在这种情况下是 bash 进程)。

【讨论】:

  • 由于他在后台执行,他可以将它们切换回来。孩子的管道仍然会被切换。
猜你喜欢
  • 2022-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
相关资源
最近更新 更多