我正在努力在linux上创建一个简单的shell.我可以创建一些东西来学习如何使用基本系统调用.
场景:命令中的用户类型,按Tab键(因此shell自动完成其命令),弹出自动完成的命令(或建议),用户按Enter键,命令evals并执行.
就像在bash中一样.
我已经想出如何进行evals,将命令转换为标记,使用管道和东西执行它.我无法弄清楚的是输入部分.即那些标签击键.
我知道我有什么选择:
getc()
- 分别获取每个字符,将其存储在缓冲区中.无法弄清楚如何获得Tab键击,因为它会暂停执行,直到它看到'\n'或Ctrl + D. 有点贵,因为命令中的每个字符都会有1个getc().另外,我将不得不处理缓冲区重新分配,摊销......嘘......scanf("%s")
- 太担心缓冲区溢出.我不能得到那些标签击键.暂停执行read()
(来自unistd.h) - 可能是我不想做的事情.但是我看到这里的人说使用它来做这件事真的很痛苦.我检查了.它是.getline()
- 无法获得Tab键击.我查看了bash源代码,看看它是如何处理输入的,以及OH MY GOD.有450行代码专门用来做这个简单的事情(input.c文件).
真的没有比这更简单的解决方案吗?我不想使用ncurses,我不关心可移植性,我只是想实现一个目标:获取用户输入并知道他何时按Tab键.尽可能少地努力,优雅地做到这一点.
要获得一些特定的自动完成功能,您可以使用GNU readline库,该库由bash
.
如果您关心终端全屏 I/O(\xc3\xa0 lavi
或emacs
),请考虑GNU ncurses。
终端是相当复杂和神秘的东西(因为它们想要模仿上个世纪奇怪的物理电传打字机)。通常,为了tty 的线路规则,一些线路处理是在内核中完成的。阅读tty 揭秘网页。因此,低级函数 \xc3\xa0 la termios(3)使用起来很神秘,您应该更喜欢像readline
或 之类的库ncurses
。
所以,不,对于自动完成的终端 I/O没有简单的解决方案,因为 tty 是复杂的东西。另请参见tty(4)和tty_ioctl(4)和pty(7)
\n\n您还可以使用strace(1)来了解由交互式 shell 等完成的所有复杂系统调用。
\n\n\n