shell在ncurses窗口?

我目前正在尝试使用ncurses编写一个最小的终端多路复用器。 但是,当我尝试执行shell时,它不会打印到窗口,而是启动一个新的子execv来控制窗口(即忽略ncurses)。

我怎样才能防止这种情况并让ncurses控制它? 有没有办法获得tty并控制它?

编辑

感谢Ross Ridge的评论,我现在知道我需要创建一个伪终端,然后我将其读入一个ncurses窗口。 但是,我无法弄清楚如何在ncurses窗口中打印stdout。 是否有读取文件描述符的ncurses函数? 或者我必须以某种方式使用printw()

您将需要大致执行以下操作:

  • 创建一个pty(伪终端)。 你没有提到你正在使用哪个操作系统,但如果它是基于POSIX的,那么man pty会有所帮助。 还看看openpty
  • pty的slave端需要连接到你正在运行的任何东西(例如shell),而master端需要连接到你的终端仿真器。
  • 因此你必须fork() ,并在子dup2dup2奴隶fd到stdinstdoutstderr
  • 然后,您需要将父级中的主fd连接到ncurses环境(用于输出)和键盘处理(用于输入)。

这个答案 , 这个答案和这个答案可能会有用,但我特别建议第一个给出Stephens 在UNIX环境中的高级编程 (我已经链接到更现代的版本), 源代码是可下载的。 买这本书,因为它是一个非常宝贵的资源,但是如果你查看那里的pty目录(我不会因为版权原因而复制和粘贴),你会找到一个很好的forkpty示例。

这就留下了如何从输出数据从运行的进程到ncurses 。 好吧,你需要编写一个终端模拟器。 选择要模拟的终端,读取它使用的所有控制序列,并实现所有这些控制序列。

如果这听起来很像辛苦(它是),我建议你看看使用tmuxscreen ; 后者完全符合您的要求,包括完整的VT100 / ANSI终端仿真器; 前者几乎完整。 tmux是一个BSD许可程序,这意味着您可以简单地调整源代码,以便在不太可能发生的情况下进行竞标。 screen是GPL,所以除非您的程序也是GPL,否则它仅供参考。