伪终端中的 Ncurses 程序

2024-03-17

在我不断尝试了解伪终端如何工作的过程中,我编写了一个小程序来尝试运行 bash。

问题是,我的断线似乎已经关闭。 (shell 提示符仅在我按 Enter 键后出现。)

此外,我仍然无法正确使用 ncurses 程序,例如 vi。谁能告诉我如何为此设置伪终端?

我写得不好的程序可以在这里找到,我鼓励你编译它 http://pastebin.com/xaj2cSsv。操作系统是 GNU/Linux,谢谢。

编辑:像这样编译:gcc program.c -lutil -o program

再次编辑:看起来奇怪的间距问题是由于使用 printf() 造成的,但仍然无法解决 ncurses 程序的问题。


您的程序中有几个问题。有些相对容易修复,而另一些则不太容易修复:

  1. forkpty() http://linux.die.net/man/3/forkpty和它的朋友来自 BSD 和不兼容 POSIX。新程序应避免使用它们。来自pty(7) manual page http://linux.die.net/man/7/pty:

    从历史上看,已经发展了两种伪终端 API:BSD 和 System V。SUSv1 基于 System V API 标准化了伪终端 API,并且该 API 应该在所有使用伪终端的新程序中使用。

    你应该使用posix_openpt() http://linux.die.net/man/3/posix_openpt反而。这个问题可能并不重要,但您应该意识到这一点。

  2. 您将调用混合到原始系统调用(read() http://linux.die.net/man/2/read, write() http://linux.die.net/man/2/write) 和文件流 (printf() http://linux.die.net/man/3/printf, fgets() http://linux.die.net/man/3/fgets) 功能。这是一个很好的迷惑自己的方法。一般来说你应该选择one接近并坚持下去。在这种情况下,最好使用低级系统调用(read() http://linux.die.net/man/2/read, write() http://linux.die.net/man/2/write)以避免因 C 库函数使用的 I/O 缓冲区的存在而引起的任何问题。

  3. 您假设您的终端采用基于线路的范例,通过使用printf() http://linux.die.net/man/3/printf and fgets() http://linux.die.net/man/3/fgets。这并不总是正确的,尤其是在处理像这样的交互式程序时vim.

  4. 您假设采用 C 风格的单字节空终止字符串范例。终端通常处理字符和字节,而不是字符串。虽然大多数字符集编码避免使用零字节,并非所有人都这样做.

  5. 由于上述 (2)、(3) 和 (4),您没有使用read() http://linux.die.net/man/2/read and write() http://linux.die.net/man/2/write正确。您应该使用它们的返回值来确定它们处理了多少字节,而不是基于字符串的函数,例如strlen() http://linux.die.net/man/3/strlen.

  6. 在我看来,这是最难解决的问题:您隐含地假设:

    • 终端(或其驱动程序)是无状态的:它不是。时期。我怀疑至少有两个状态控制是导致基于 ncurses 的程序无法正常工作的原因:行模式 http://en.wikipedia.org/wiki/Terminal_%28telecommunication%29#Modes本地回声控制 http://en.wikipedia.org/wiki/Echo_%28computing%29终端的。至少这些必须在父/主终端和从终端之间匹配,以避免各种奇怪的伪影。

    • 只需来回传递字节即可传递终端的控制接口:但情况并非总是如此。现代虚拟终端允许通过以下方式进行一定程度的带外控制ioctl() http://linux.die.net/man/2/ioctl调用,如针对 Linux 的描述here http://linux.die.net/man/4/tty_ioctl.

    处理这个问题的最简单方法可能是将父终端设置为原始模式,并让从属伪终端驱动程序处理尴尬的细节。

您可能想看看这个程序 http://man7.org/tlpi/code/online/dist/pty/script.c.html这似乎工作正常。它来自书本Linux 编程接口 http://www.man7.org/tlpi/完整的源代码是here http://man7.org/tlpi/code/online/index.html. 免责声明:我没有读过这本书,也不是在宣传它 - 我只是使用 Google 找到了该程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

伪终端中的 Ncurses 程序 的相关文章

随机推荐

  • iPhone 上的色彩平衡

    我正在拍摄一张图像 通过屏幕上下文加载它 并逐像素地更改它 我有许多不同的滤镜应用于图像 但我需要做的最后一件事是改变色彩平衡 类似于 Photoshop 以使红色更加青色 下面的代码显示了我如何拍摄图像 获取数据以及逐像素检查 r g b
  • 使用 hash_hmac 和ripemd160 快速散列字符串

    我正在尝试使用 Swift 3 和 或 Objective C 对字符串进行哈希处理ripemd160模拟以下 php 的输出 string string key test hash hmac ripemd160 string key ou
  • 在 PowerPoint 中重命名对象

    可能是一个非常愚蠢的问题 但我不知道如何在 PowerPoint 中重命名对象 例如 我所有的图表默认称为 图表 1 等 有人可以帮我吗 谢谢 在 PowerPoint 2007 中 您可以从 选择 窗格执行此操作 要显示选择窗格 请单击功
  • 尽管在本地主机上工作,但部署到 Azure 时,Azure Active Directory 始终重定向到“~/.auth/login/done”

    因此 我正在开发一个 ASP NET Core 应用程序 NET Core 2 0 作为 Azure 上的应用服务托管 我想使用单个租户 因此只有我们公司的帐户 通过 Azure AD 实施身份验证 实际上 我添加了所有必要的代码 注册了应
  • 在 Outlook 中执行搜索查询

    您好 我想知道是否可以从我的 WinForms 应用程序向 Outlook 2010 发送搜索查询 也就是说 不是像我一直在搜索并找到的那样搜索 PST 文件 而是尝试在 Outlook 中显示结果列表 就像我自己在搜索框中键入内容一样 如
  • ELM QueryString 解析器无法编译

    我真的很想学习一些 ELM 但是我的思想在查询解析时崩溃了 我的想法是创建一个函数来按名称获取查询字符串值 例如 给定一个查询字符串 name Neuber像这样的函数getParam name 那会返回Neuber 但它在最基本的例子中失
  • wxpython滚动面板不更新滚动条

    我正在使用 winxp 和 wxpython wxpython 3 1 python 2 6 制作一个 GUI 程序 它将文本从 TextCtrl 复制到包含 StaticText 的 ScrollablePanel 中 这一切都工作正常
  • 在内容安全策略中将多个域列入白名单

    我正在编写一个 chrome 扩展 它的白名单中需要有两个域以用于内容安全策略 我已经查看了官方文档 但似乎仍然无法弄清楚正确的语法 以下似乎不起作用 content security policy script src self http
  • AWS NodeJS SDK V3 DynamoDB UpdateItem - TypeError:无法读取未定义的属性“0”

    我正在尝试使用新的适用于 NodeJS 的 AWS SDK V3 在 NodeJS 中进行基本的数据库更新操作 我尝试更新的数据对象如下所示 auth BOOL false username S siegbert secondsLeft N
  • 如何查看和复制 R 默认 Makevars 配置?

    我没有 R Makevars文件和 gt tools makevars user character 0 gt tools makevars site character 0 Yet R必须从某处读取配置 cpp文件包含Rcpp导出到包中s
  • 计算公式的子公式

    选择有公式的单元格后 我们可以在Excel公式栏中选择其公式的一部分并进行计算 按F9 我需要通过 JavaScript API 重现子公式的计算 例如 假设 Cell 的值A1 B1 C1分别是1 2 3 和细胞D1包含一个公式 A1 B
  • 将 2d int 数组转换为 2d double 的最短方法

    我有一个方法只能得到double 我想传递给int 在java中有没有一种简单的方法可以做到这一点 就像这样简单 int iArray 1 2 5 6 double dArray double iArray 不幸的是 转换数组的唯一方法是迭
  • 使声明的名称空间正常工作时遇到问题

    我试图获取用外部 css 编写的命名空间 实际上是两个单独的文件 当我在浏览器上运行该文件时 它不会使用声明的名称空间 我认为该文件正在调用 css 文件 但它没有应用命名空间样式 HTML
  • Fortran 接受来自 C 的字符串(?)

    我觉得这应该是一个简单的问题 但我无法让它发挥作用 我有一些 Fortran 代码 需要如下输入 SUBROUTINE TRACE X Y NAME XX YY EXTERNAL NAME CALL NAME X Y XX YY 我正在尝试
  • ILookup 不应该在 TElement 中(声明)协变吗?

    定义System Linq ILookUp
  • 在两个不同的系统之间同步对象,最好的方法是什么?

    我正在致力于使用基于 XML 的有效负载在 iPhone 和网站之间同步两个业务对象 并且很乐意征求一些关于最佳例程的想法 这个问题的本质是相当通用的 我可以看到它适用于需要在 Web 实体和客户端 桌面 移动电话等 之间同步业务对象的各种
  • 我什么时候会在 ASP.NET 中使用委托?

    我一直在寻找一种方法来使用我能使用的所有工具 并超越我目前的水平 但是 尽管我读过有关委托的内容 但我永远找不到使用它们的地方 例如接口 泛型和很多东西 但我离题了 我希望有人可以向我展示他们何时以及如何使用委托在webasp net c
  • 与 Paramiko 的无密码 SSH 连接失败,而 SSH 可以正常连接

    我打算在客户端和服务器之间使用 SSH 密钥创建无密码连接 使用 paramiko 我最终得到了认证异常 通过 Popen 使用标准 SSH 我可以毫无问题地连接 对于 Paramiko 我使用以下代码 client paramiko SS
  • jQuery 中的简单淡入和可见性

    我正在尝试更改 css 属性visibility一个 div 到visible用 jQuery fadeIn 过渡 这是我的代码 a click function test fadeIn slow function this css vis
  • 伪终端中的 Ncurses 程序

    在我不断尝试了解伪终端如何工作的过程中 我编写了一个小程序来尝试运行 bash 问题是 我的断线似乎已经关闭 shell 提示符仅在我按 Enter 键后出现 此外 我仍然无法正确使用 ncurses 程序 例如 vi 谁能告诉我如何为此设