![保存光标位置并在终端中恢复它](https://linux22.com/image/6691/%E4%BF%9D%E5%AD%98%E5%85%89%E6%A0%87%E4%BD%8D%E7%BD%AE%E5%B9%B6%E5%9C%A8%E7%BB%88%E7%AB%AF%E4%B8%AD%E6%81%A2%E5%A4%8D%E5%AE%83.png)
我正在使用一些终端功能来创建异步提示输出bash
。我想要得到这样的东西:在 中输出字符串时PROMPT_COMMAND
,保存终端光标位置,打印 put...
并执行其他操作(例如打印其他信息);然后过了一段时间回去记住位置并打印新的东西。PS1
设计的方式是将命令本身放在换行符上,以便异步输出只是终端中的文本。
我发现cup
terminfo 条目将光标移动到给定位置,并且有转义码来获取当前位置(例如,请参阅这个问题)。但对我来说,似乎它们都使用屏幕上的光标位置,而不是终端缓冲区中的位置。这意味着在添加新线后我记住的位置将是错误的。
有没有办法使用终端光标位置来根据缓冲区位置存储和恢复光标位置?您可以假设记住的位置仍然位于缓冲区的可见部分(因此您实际上可以将光标放在那里),但它可能会上升几行。现在,我们不考虑竞争条件。如果没有,我会尝试寻找其他技巧。
有zsh
一个 shell 实际上具有异步提示支持,但我实际上不知道如果在输出之前用户按下Enter转到新行,它是否会起作用。
答案1
您可能使用的大多数终端都实现转义序列来保存和恢复光标位置。这些是终端描述中的sc
(保存光标)和(恢复光标)功能,您可以通过(就像)使用它们:rc
tput
cup
tput sc
tput cup 50 10
echo some stuff
echo more stuff
tput rc
但是,如果您的程序写入了足够的文本来强制滚动,则恢复的位置仍将位于终端屏幕上的同一位置。它不会随着滚动的文本一起移动。
顺便说一句,仅 POSIX 文档部分因为tput
该工具实际上是另一个标准 X/Open Curses 的一部分。这被总结在可移植性手册页的部分。
回到问题:没有跟踪的转义序列缓冲位置(考虑滚动)。为此,您的应用程序必须跟踪发送到屏幕的内容。解决这类问题就是curses 库的用途。在普通的命令行应用程序中,您无能为力。