我正在写一个终端聊天,如果来自另一个用户的新消息异步到达,我想重新打印用户输入的内容。
如果有新消息到达我打印" \ x1B [2K"到stdout(用于擦除当前行的ANSI ESCAPE CODE)清除当前行,然后我打印" \ r"将光标移动到最左边的位置,然后用新行打印收到的消息
现在我想重新打印用户键入的字符 - 我发现有一个特殊字符VREPRINT(http://www.gnu.org/software/libc/manual/html_node/Editing-Characters.html)可以使用,如果命中CTRL-R它实际上有效...但是如果使用结构termios的c_cc [VREPRINT]中放置的字符将字符打印到stdout,它就不起作用 - 甚至可以这样做吗?
我不想使用任何其他库,如readline或ncurses,因为这可能是明显的矫枉过正......我只是想让我的解决方案在可能的情况下使用ICANON终端模式工作
提前致谢!
答案 0 :(得分:1)
虽然可以写入您正在读取的相同tty设备,但这并不意味着出现的字符将被处理为输入字符。
您可以使用两个单独的shell会话(使用screen
,tmux
,或者如果您使用的是MacOSX,iTERM.app
个会话,自行测试。
获取当前的tty名称:
tty
我们假设第1节的tty名称为/dev/ttys000
。
然后输入以下内容,不返回或换行 - 只需将其保留为待处理状态:
echo abc def-
在会话2 (使用会话1中的tty名称)中,输入以下命令:
echo foo >/dev/ttys000
字符串foo
应出现在会话1中的待定行中,如下所示:
echo abc def-foo
现在,回到Session 1,点击“enter”(或返回),导致输入缓冲区完成并发送到shell,它会将第一个单词解析为echo
命令,将后续参数作为要打印的文本。
您应该看到字符串“abc def-
”已回显 - 但不 foo
。
此测试清楚地表明字符串foo
从未放入输入缓冲区,即使它被发送到用于输入(和输出)的相同tty。
您可以尝试查看特殊控制字符是否被识别和处理;但他们不会。这些字符只是输出到终端,但没有处理。
为了处理特殊字符,必须通过连接到输入设备的插座接收它们。
要完成您要执行的操作,您必须执行非规范(stty -icanon
)并处理代码中的每个字符,以便收集挂起的输入并且还能够生成异步输出
或者,使用nurses
并不难,如果您正在编写基于终端的聊天程序,我建议至少创建两个面板:所有输出的“聊天”面板,以及“输入“用于用户输入的面板。这允许来自其他用户的输出以及来自“输入”面板的完成的命令被异步地接收和写入“聊天”面板,而不会干扰用户在“输入”面板中正在进行的当前命令。 / p>