最近写myshell,其中一个基本的要求就是要实现命令的补全和,上下键翻命令,其中需要用到readline这个库。
- 安装readline
安装的话问题不太大,一个命令的事情。。。
unbuntu下,一般都是libreadline_dev软件包
$ sudo apt-get install libreadline6 libreadline6-dev
然后查看了自己的/usr/include 下面的文件……果然有了这个库。。
- readline函数
补全这个里面要涉及到一个叫readline( )的函数,在man手册中可以查看这个函数的具体使用,但是当时我还是很不太理解,这个要怎么用。
其中可以知道它返回的是一个char类型的指针,readline将从终端读取一行,并使用prompt返回prompt指针指向的字符串作为一个提示。如果提示符为NULL或空字符串,则没有提示符
发行。返回的行是需要给接受的指针一个动态分配的,使用结束后需要free。
char *line;
char *str=">>";
line = (char *)malloc(256);
line = readline(str);
free(line);
/*此时从终端读取的字符就返回到了line中,str只是一个输出,显示*/
readline只是支持当前目录文件的补全,比如内置命令无法补全,问题,还有空格问题的处理,其实可以通过对readline进行一些处理,用起来更方便,引用一个处理空格的代码。
char* stripwhite (char *line)
{
register char *s, *t;
for (s = string; whitespace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && whitespace (*t))
t--;
*++t = '\0';
return s;
}
/*line就是使用readline函数的返回指针,whitespace去除空格*/
- 链接库
编译的时候记得连接下readline这个库
gcc myshell.c -lreadlien
然后就很好用了,如果要在下面解析readlien返回的字符的时候,建议可以用strcpy(buf,line)拷贝下,然后再来操作buf。
- 对readline的运用
void input (char *buf)
{
char *line, *s;
struct passwd *pwd;
struct hostent *hp;
char *path;
char *home;
char st[256] = {0};
char host[100] = {0};
char N_path[2560]={0};//N_path[0]='~';
char *p;
char *q;
home = (char *)malloc(20);
line = (char *)malloc(256);
path = (char *)malloc(2560);
/*获取主机名称和用户名称*/
if(gethostname(host,sizeof(host))<0)
{
perror("gethostname");
}
hp = gethostbyname(host);
pwd = getpwuid(getuid());
/*获取当前目录显示*/
home = getenv("HOME");
home[strlen(home)+1]='\0';
p = home;
getcwd(path,256);
path[strlen(path)]='\0';
q = path;
while(*p!='\0')
{
p++;//home
q++;//path
}
strcpy(N_path,q);
N_path[strlen(N_path)+1]='\0';
sprintf(st,"\033[;36m %s@%s \033[0m:\033[;34m ~%s \033[0m",pwd->pw_name,hp->h_name,N_path);
initialize_readline();
line = readline (st);
//strcpy(buf,line);
if (!line)
return;
s = stripwhite (line);
strcpy(buf,s);
if (*s)
{
add_history(s);
}
free(line);
}