【发布时间】:2016-05-11 05:32:46
【问题描述】:
作为一个更好地理解我的计算机的练习,作为一个工具,我正在用 C++ 编写my own shell。 Stephen Brennan's article on writing a simple shell 很有帮助。
然而,让我困惑的是如何处理按向上箭头和向下箭头滚动浏览我的命令历史记录。
我尝试了
ncurses,但这会替换整个屏幕,而系统提供的 shell 似乎只是继续写入终端。我尝试使用
tcgetattr关闭规范模式,但是虽然这让我可以在键入时按下箭头键,但它也会关闭对文本导航的左/右箭头键的所有处理,并且退格键和 Ctrl-C ...虽然我自己可能会发送一个信号来响应 Ctr-C,但我不知道如何让终端将光标移回(除了输出“返回”并重新写行的开头)。它似乎也给了我不同的转义序列,这取决于我是在 Xcode 的“哑”终端还是在我的 Mac 的 Terminal.app 中运行。我查看了
fishShell 和bash的来源,但似乎太多内容无法找到相关部分。 p>
标准外壳如何处理接收按键?他们如何处理移动光标和退格?他们如何在不占用屏幕的情况下重写一行的部分内容?是否有一个标准来定义外壳需要做什么?
PS - 我知道如何记录以前的命令。实际上是在键入时得到按键,而不是在有人按下返回之后,我无法开始工作。
【问题讨论】:
-
使用GNU readline 或等效的BSD editline。
-
Close-voters:我希望你已经阅读了更新后的问题,现在看起来很好:)
-
我根本不知道它实际上是如何实现的,但我怀疑 shell 正在重写整个屏幕(à la
ncurses)。例如,如果我在bash中按 C-l,它将清除整个屏幕。这表明 shell 不仅仅是一次管理一行。我认为像readline这样的库同样会接管整个终端。 -
@WaleedKhan 他们不会接管屏幕。 Terminal.app 默认为 bash。如果我现在输入
ksh并按回车键,我会得到一个 Korn Shell,它会愉快地继续在前面的 bash 命令下面编写。因此,必须有一种方法可以让完全不同的可执行文件取代前一个可执行文件中断的地方。 -
@uliwitness 我认为您可以只查询当前光标位置的位置,然后从那里继续写入。我不使用
ncurses或类似的,所以我不能肯定地说。