在C中的自定义shell中实现向上箭头键和Tab自动完成
我正在制作我自己的shell,我正在尝试实现这样一种用法:当按下箭头键时,它返回我键入的最后一个内容,或者tab auto complete,就像Linux终端一样,当我按下箭头键时,我在屏幕上看到:“^[[A”,或使用tab我只得到了一个表格,如何在我的代码中实现这一点?我尝试使用诸如、、之类的库,并在makefile中在文件末尾添加-lreadline-lncures,如下所示:在C中的自定义shell中实现向上箭头键和Tab自动完成,c,linux,terminal,readline,C,Linux,Terminal,Readline,我正在制作我自己的shell,我正在尝试实现这样一种用法:当按下箭头键时,它返回我键入的最后一个内容,或者tab auto complete,就像Linux终端一样,当我按下箭头键时,我在屏幕上看到:“^[[A”,或使用tab我只得到了一个表格,如何在我的代码中实现这一点?我尝试使用诸如、、之类的库,并在makefile中在文件末尾添加-lreadline-lncures,如下所示: CFLAGS = -Wall -pedantic myshell: main.o myShell.o
CFLAGS = -Wall -pedantic
myshell: main.o myShell.o
gcc $(CFLAGS) -o myshell main.o myShell.o -lreadline -lncurses
main.o: main.c
gcc $(CFLAGS) -c main.c -o main.o
myShell.o: myShell.c
gcc $(CFLAGS) -c myShell.c -o myShell.o
clear:
rm -f myshell *.o *.out
int main(int argc, char *argv[])
{ /* shell loop */
char command[COMMAND_BUFFER_SIZE];
char *tokens[TOKEN_BUFFER_SIZE];
int token_Size = 0;
int blk = 0;
int aux = 0;
if (argc == 2)
{
inputOption(&argv[1][0]);
exit(0);
}
signal(SIGINT, handlerC);
signal(SIGTSTP, handlerZ);
signal(SIGQUIT, handlerBS);
//kill(getpid(), SIGSTOP);
while (1)
{
using_history();
do
{
customPrompt();
fgets(command, COMMAND_BUFFER_SIZE, stdin);
} while (strlen(command) < 2);
token_Size = 0;
token_Size = parse(command, tokens, token_Size);
...
}
但是什么也没发生,我需要包括什么吗?以防万一,我有一个函数,我在终端中读取我键入的内容,如下所示:
CFLAGS = -Wall -pedantic
myshell: main.o myShell.o
gcc $(CFLAGS) -o myshell main.o myShell.o -lreadline -lncurses
main.o: main.c
gcc $(CFLAGS) -c main.c -o main.o
myShell.o: myShell.c
gcc $(CFLAGS) -c myShell.c -o myShell.o
clear:
rm -f myshell *.o *.out
int main(int argc, char *argv[])
{ /* shell loop */
char command[COMMAND_BUFFER_SIZE];
char *tokens[TOKEN_BUFFER_SIZE];
int token_Size = 0;
int blk = 0;
int aux = 0;
if (argc == 2)
{
inputOption(&argv[1][0]);
exit(0);
}
signal(SIGINT, handlerC);
signal(SIGTSTP, handlerZ);
signal(SIGQUIT, handlerBS);
//kill(getpid(), SIGSTOP);
while (1)
{
using_history();
do
{
customPrompt();
fgets(command, COMMAND_BUFFER_SIZE, stdin);
} while (strlen(command) < 2);
token_Size = 0;
token_Size = parse(command, tokens, token_Size);
...
}
编辑:以防万一,我会添加我在这个程序中包含的库
#include <stdio.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <grp.h>
#include <limits.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <fcntl.h>
#include <ncurses.h>
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
有人能帮我一把吗?我想你们必须把终端切换到一种特殊模式,这种模式会把特殊的组合传递给你们的程序。不知道怎么做,
ncurses
docs可能会澄清。我会亲自查看GNU Readline。但我明白,只包括它的头如果您没有实际调用库的任何函数,则将库链接到程序将毫无用处。特别是,您可能希望通过它的函数获取命令输入。您可能还需要根据自己的需要对其进行配置,无论是以编程方式、配置文件还是两者兼而有之。@JohnBollinger我认为在使用add_history()时,我在管理它,是这个函数完成了向上箭头的工作,而不是readline():/@IvoFerrari,如果您希望shell能够立即响应用户的击键,那么自然地,这必须由实际读取击键的任何函数来处理。fgets()
不能做到这一点——你所能做的就是终端设备在默认情况下所做的一切。可能不仅仅是使用readline()
而不是fgets()
,而是更换fgets())
对于其他事情,您肯定需要做一件事。我假设您必须将终端切换到一种特殊模式,该模式将向您的程序传递特殊的组合。不确定如何做到这一点,ncurses
文档可能应该能够澄清。我会亲自查看GNU Readline。但我明白,包括我在内如果您不实际调用库的任何函数,则ts头和将库链接到程序将毫无用处。特别是,您可能希望通过其函数获取命令输入。您可能还需要根据需要对其进行配置,无论是以编程方式、通过配置文件还是两者兼而有之。@JohnBollinger我认为在使用add\u history时(),我在管理它,是这个函数做了向上箭头的工作,而不是readline():/@IvoFerrari,如果你想让shell对用户的击键立即做出响应,那么自然地,这必须由实际读取击键的任何函数来处理。fgets()
不能做到这一点——你所能得到的只是终端设备默认情况下所做的任何事情。可能需要做的不仅仅是使用readline()
而不是fgets()
,但是将fgets()
换成其他东西肯定是你需要做的一件事。