Table of Contents

part1: readline安装

part2:readline使用举例

part3: readline下的IO复用


http://m.blog.chinaunix.net/uid-29547110-id-5047281.html

Linux下应用程序可能需要交互式输入命令,但普通的标准IO进行命令输入显得有些呆板,人性化不足。本文讲述使用libreadline库,实现类似sh的交换终端:支持命令自动补全,支持历史命令等。

part1: readline安装

(1) 下载readline源码:http://download.chinaunix.net/download/0009000/8886.shtml
(2) 解压后, 在源码目录依次执行 ./configure, make, sudo make install 完成安装

part2:readline使用举例

#include <stdlib.h>
#include <stdio.h> //注意,readline.h中可能需要调用标准IO库的内容,所以stdio.h必须在readline.h之前被包含
#include <readline/readline.h>
#include <readline/history.h>/*
* 真正的命令执行函数
* 测试时,被定义为桩函数了
*/
int com_list(char *para)
{printf("do com_list:%s\n", para);return 0;
}int com_view(char *para)
{printf("do com_view:%s\n", para);return 0;
}int com_rename(char *para)
{printf("do com_rename:%s\n", para);return 0;
}
int com_stat(char *para)
{printf("do com_stat:%s\n", para);return 0;
}int com_pwd(char *para)
{printf("do com_pwd:%s\n", para);return 0;
}
int com_delete(char *para)
{printf("do com_delete:%s\n", para);return 0;
}
int com_help(char *para)
{printf("do com_help:%s\n", para);return 0;
}int com_cd(char *para)
{printf("do com_cd:%s\n", para);return 0;
}
int com_quit(char *para)
{printf("do com_quit:%s\n", para);exit(0);
}/*
* A structure which contains information on the commands this program
* can understand.
*/
typedef struct {char *name;            /* User printable name of the function. */rl_icpfunc_t *func;        /* Function to call to do the job. */char *doc;            /* Documentation for this function. */
} COMMAND;COMMAND commands[] = {{ "cd", com_cd, "Change to directory DIR" },{ "delete", com_delete, "Delete FILE" },{ "help", com_help, "Display this text" },{ "?", com_help, "Synonym for `help'" },{ "list", com_list, "List files in DIR" },{ "ls", com_list, "Synonym for `list'" },{ "pwd", com_pwd, "Print the current working directory" },{ "quit", com_quit, "Quit using Fileman" },{ "rename", com_rename, "Rename FILE to NEWNAME" },{ "stat", com_stat, "Print out statistics on FILE" },{ "view", com_view, "View the contents of FILE" },{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
};char* dupstr(char *s)
{char *r;r = malloc (strlen (s) + 1);strcpy(r, s);return (r);
}// clear up white spaces
char* stripwhite (char *string)
{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;
}/*
* Look up NAME as the name of a command, and return a pointer to that
* command. Return a NULL pointer if NAME isn't a command name.
*/
COMMAND *find_command (char *name)
{register int i;for (i = 0; commands[i].name; i++)if (strcmp (name, commands[i].name) == 0)return (&commands[i]);return ((COMMAND *)NULL);
}/* Execute a command line. */
int execute_line (char *line)
{register int i;COMMAND *command;char *word;/* Isolate the command word. */i = 0;while (line[i] && whitespace (line[i]))i++;word = line + i;while (line[i] && !whitespace (line[i]))i++;if (line[i])line[i++] = '\0';command = find_command (word);if (!command){fprintf (stderr, "%s: No such command for FileMan.\n", word);return (-1);}/* Get argument to command, if any. */while (whitespace (line[i]))i++;word = line + i;/* Call the function. */return ((*(command->func)) (word));
}/*
* Generator function for command completion. STATE lets us know whether
* to start from scratch; without any state (i.e. STATE == 0), then we
* start at the top of the list.
*/
char* command_generator (const char *text, int state)
{static int list_index, len;char *name;/* * If this is a new word to complete, initialize now. This includes* saving the length of TEXT for efficiency, and initializing the index* variable to 0.*/if (!state){list_index = 0;len = strlen (text);}/* Return the next name which partially matches from the command list. */while (name = commands[list_index].name){list_index++;if (strncmp (name, text, len) == 0)return (dupstr(name));}/* If no names matched, then return NULL. */return ((char *)NULL);
}/*
* Attempt to complete on the contents of TEXT. START and END bound the
* region of rl_line_buffer that contains the word to complete. TEXT is
* the word to complete. We can use the entire contents of rl_line_buffer
* in case we want to do some simple parsing. Return the array of matches,
* or NULL if there aren't any.
*/
char** fileman_completion (const char *text, int start, int end)
{char **matches;matches = (char **)NULL;/* * If this word is at the start of the line, then it is a command* to complete. Otherwise it is the name of a file in the current* directory. */if (start == 0)matches = rl_completion_matches (text, command_generator);return (matches);
}/*
* Tell the GNU Readline library how to complete. We want to try to complete
* on command names if this is the first word in the line, or on filenames
* if not.
*/
void initialize_readline ()
{/* Allow conditional parsing of the ~/.inputrc file. */rl_readline_name = ">";/* Tell the completer that we want a crack first. */rl_attempted_completion_function = fileman_completion;
}int main (int argc, char **argv)
{char *line, *s;initialize_readline();    /* Bind our completer. *//* Loop reading and executing lines until the user quits. */for ( ; ;){line = readline (">: ");if (!line)break;/* * Remove leading and trailing whitespace from the line.* Then, if there is anything left, add it to the history list* and execute it. */s = stripwhite (line);if (*s){add_history(s);execute_line(s);}free(line);}exit(0);
}

编辑运行:

$ gcc readline.c  -lreadline
$ ls
a.out  readline.c
[rongtao@toa readline]$ ./a.out
>:
?       cd      delete  help    list    ls      pwd     quit    rename  stat    view
>: cd
do com_cd:
>: delete
do com_delete:
>: ?
do com_help:
>: stat
do com_stat:
>: quit
do com_quit:
$ 

part3: readline下的IO复用

static void handle_command (char *line)
{...
}int
main (int argc, char **argv)
{int netfdfd_set allfd;int maxfd;netfd = connect_to_server ();FD_ZERO (&allfd);FD_SET (fileno(stdin), &allfd);FD_SET (netfd, &allfd);maxfd = netfd;rl_callback_handler_install ("ccnet> ", handle_command);while (1) {fd_set rfds;int retval;rfds = allfd;retval = select (maxfd + 1, &rfds, NULL, NULL, NULL);if (retval < 0)perror ("select");if (FD_ISSET(0, &rfds))rl_callback_read_char();if (FD_ISSET(netfd, &rfds))read_from_network (netfd);}
}

关于readline更多的使用请自行阅读readline的man文件。

readline库实现命令行自动补全相关推荐

  1. ubuntu使用zsh进行命令行自动补全

    文章目录 ubuntu使用zsh进行命令行自动补全 1.zsh下载及配置 安装zsh 安装ohmyzsh 安装必要的插件 修改zshrc 使能代码提示 2.安装terminator终端 3.进入zsh ...

  2. Python命令行自动补全和记录历史命令

    2019独角兽企业重金招聘Python工程师标准>>> ~$ cat .pythonstartup import os import readline import rlcomple ...

  3. mac 终端命令行自动补全并且忽略大小写

    1.终端命令补全工具bash-completion 通过Homebrew包管理工具来安装,首先需要安装brew,然后执行安装命令: brew install bash-completion 2.终端命 ...

  4. linux “命令行自动补全”功能用命令

    是按Tab键,左上角ESC的下面两个,如果你当前目录只有一项,只需要直接Tab,如果有多项,输入前面不同的部分再Tab,一般输入3个字母就可以,如果按一下没效果,按两下会列出所有项,然后再输入一点自己 ...

  5. Mac下的命令行自动补全功能

    /usr/local/etc/bash_completion.d 转载于:https://www.cnblogs.com/shengulong/p/10534628.html

  6. 这个库厉害了,自动补全Python代码,节省50%敲码时间

    点击"小詹学Python",选择"星标"公众号 第一时间速享重磅干货 本文转自 机器之心,禁止二次转载 摘要:介绍一个优秀代码自动补全工具库. 近日,Reddi ...

  7. 这个库厉害了,自动补全 Python 代码,节省 50% 敲码时间

    原文: https://blog.csdn.net/qq_4320... 摘要:介绍一个优秀代码自动补全工具库. 近日,Reddit 上的一篇帖子引起了网友的热议.帖子作者「mlvpj」称: 「我们使 ...

  8. linux运行fastboot脚本,fastboot命令的自动补全

    在Ubuntu 13.10以及之后的Ubuntu 14.04上,通过APT安装fastboot以及adb工具之后,发现fastboot的自动补全有问题了, fastboot flash 之后的自动补全 ...

  9. python最新技术开锁工具_这个库厉害了,自动补全 Python 代码,节省 50% 敲码时间...

    摘要:介绍一个优秀代码自动补全工具库. 近日,Reddit 上的一篇帖子引起了网友的热议.帖子作者「mlvpj」称: 「我们使用深度学习完成了一个简单的项目,可以自动进行 Python 代码补全.」 ...

最新文章

  1. 简单粗暴地理解js原型链–js面向对象编程
  2. java抽象类与接口区别6_java基础知识(6)---抽象类与接口
  3. 深度学习总结:GAN,3种方式实现fixedGtrainD,fixedDtrainG, retain, detach
  4. 常熟理工学院计算机网络基础,常熟理工学院计算机网络复习题之简答题
  5. ArcMap 导入 wrl_flmic拍摄的素材如何无损导入电脑
  6. 基于JAVA+Servlet+JSP+MYSQL的实验室机房预约管理系统
  7. 1177: 按要求排序(指针专题)_L2算法基础第10课 排序中
  8. java excel 合并两个单元格内容 无法换行_12个简单高效的EXCEL小技巧,让你秒变职场达人!...
  9. python画折线图-利用python画出折线图
  10. stl标准模板库_如何在C ++ STL(标准模板库)中使用Pair
  11. AWS 技术峰会真的50%都是技术
  12. python自动发公众号_itchatmp | 基于python微信公众号接口
  13. tplink710n无线打印服务器,tplink710n设置
  14. 北京交通大学计算机学院篮球,院际杯篮球赛|土建计算机相会决赛!男篮半决赛战报...
  15. 如何使用prism进行统计分析(Analysis)?
  16. 51单片机外中断流水灯
  17. ## 三天打鱼两天晒网问题
  18. Kafka常用命令收录
  19. 计算机老师发展的现状,计算机专业教师队伍的现状分析.doc
  20. Python基础知识之函数篇

热门文章

  1. leetcode题解72-编辑距离
  2. Spring Mvc使用Jackson进行json转对象时,遇到的字符串转日期的异常处理(Can not deserialize value of type Date from String)
  3. AKKA Inbox收件箱
  4. 「HAOI2018」染色 解题报告
  5. Android开发--apk的生成
  6. PHP:判断客户端是否使用代理服务器及其匿名级别
  7. php header()的用法
  8. Jquery ui的dialog使用文档概述
  9. oracle 自定义函数 返回一个表类型
  10. 使用Filter实现用户自动登录