我正在尽力在 Linux 上创建一个简单的 shell。我可以创建一些东西来学习如何使用基本系统调用。
场景: 用户输入命令,按下 tab(因此 shell 自动完成他的命令),自动完成的命令弹出(或建议),用户按下 enter,命令评估并执行。
就像在 bash 中一样。
我已经弄清楚如何进行评估、将命令转换为标记、使用管道和其他东西执行它。我想不通的是输入部分。即那些 Tab 键击。
我知道我有哪些选择:
getc()
- 分别获取每个字符,并将其存储在缓冲区中。无法弄清楚如何获取 Tab 击键,因为它会暂停执行,直到看到“\n”或 Ctrl+D。有点贵,因为命令中的每个字符都有 1 个 getc()。此外,我将不得不处理缓冲区重新分配、摊销……嘘……scanf("%s")
- 过度担心缓冲区溢出。无法获得我不想要的那些选项卡击键。暂停执行read()
(来自 unistd.h)- 可能是我不想要的。但是我在这里看到有人说用它来做这件事真的很痛苦。我检查了。是的。getline()
- 无法获取 Tab 击键。
我研究了 bash 源代码,看看它是如何处理输入的,我的天哪。有 450 行代码专门用于完成这件简单的事情(input.c 文件)。
真的没有比这更简单的解决方案了吗?我不想使用 ncurses,我不关心可移植性,我只想实现一个目标:获取用户输入和知道他什么时候按了 Tab 键。以尽可能少的努力优雅地完成。
最佳答案
要获得一些特定的自动完成功能,您可以使用 GNU readline bash
使用的库。
如果您关心终端全屏 I/O(vi
或 emacs
),请考虑 GNU ncurses .
终端是非常复杂和神秘的东西(因为它们想要模拟上个世纪的怪异物理电传打字机)。通常,一些行处理是在内核中为 line discipline 完成的。 tty 的。阅读 tty demystified网页。因此,低级功能à la termios(3)使用起来很神秘,您应该更喜欢像 readline
或 ncurses
这样的库。
所以,不,没有用于自动完成的终端 I/O 的简单解决方案,因为 ttys 是复杂的东西。另见 tty(4) & tty_ioctl(4) & pty(7)
你也可以使用 strace(1)了解所有的复杂system calls由例如完成交互式外壳。
关于c - 在 Linux 上处理用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475465/