Linux---more命令学习
More命令
more命令一般用于分页显示文件的内容,more会显示文件第一屏的内容,在屏幕的底部,more用反白字体显示文件的百分比,这时如果按空格键,文件下一屏内容会显示出来,如果按回车键,显示的则是下一行,如果输入“ q ”,则是结束显示。
more命令的几种用法
第一种:
$ more filename
显示文件filename的内容。
第二种:
$ command | more
将command命令的输出分页显示。
第三种:
$ more < filename
从标准输入获取要分页显示的内容,而这时more的标准输入被重定向到文件filename。
more命令的工作流程
+-----------> 显示24行
| +------> 输入操作,打印信息
| | 可以输入回车键、空格键、q键
| +------> 输入回车键,打印一行
+ ---------> 如果空格键,打印24行
如果是q键 ---> 退出
more命令的编写---版本1
1 #include <stdio.h>2 #include <stdlib.h>3 4 #define PAGELEN 245 #define LINELEN 5126 7 void do_more(FILE *);8 int see_more();9
10 int main(int ac,char *av[])
11 {
12
13 FILE *fp;
14 if(ac == 1)
15 do_more(stdin);
16 else
17 while(--ac)
18 if((fp = fopen(* ++av,"r")) != NULL)
19 {
20 do_more(fp);
21 fclose(fp);
22 }
23 else
24 exit(1);
25
26 return 0;
27 }
28
29
30 void do_more(FILE *fp)
31 {
32 char line[LINELEN];
33 int num_of_lines = 0;
34 int see_more(),reply;
35
36 while(fgets(line, LINELEN,fp))
37 {
38 if(num_of_lines == PAGELEN)
39 {
40 reply = see_more();
41
42 if(reply == 0)
43 break;
44
45 num_of_lines -= reply;
46 }
47 if(fputs(line,stdout) == EOF)
48 exit(1);
49
50 num_of_lines++;
51 }
52 }
53
54 int see_more()
55 {
56 int c;
57 printf("\033[7m more?\033[m");
58 while((c = getchar()) != EOF)
59 {
60 if(c == 'q')
61 return 0;
62 if(c == ' ')
63 return PAGELEN;
64 if(c == '\n')
65 return 1;
66
67 }
68 return 0;
69 }
fopen 打开文件,打开成功返回一个指向该文件的文件指针,失败返回NULL。
fgets 从指定的文件中获取数据,每次读一行,并存入指定的buffer中最多读size - 1个
fputs 把字符串输出到stram中,但不输出空字符。发生错误,则输出EOF
getchar 从标准输入获取一个字符,相当于getc(stdin)
more版本1的问题:
1.当屏幕上的文字上滚时,[ more ]字符也会随之上滚,
![](/assets/blank.gif)
2.当我们按下空格或者 "q" 后,如果没有按下回车,程序没有任何反应。
自己编写的more命令分析
我们首先使用linux自带的more命令
$ ls /bin | more
很明显,我们想做的是将/bin 目录下的文件分页显示,在使用 “ | ”管道命令把 ls 的输出重定向到 more的输入,并且等待我们输入命令,结果是令人满意的。
我们再使用自己编写的more命令
$ls /bin | more_v1
发现和linux自带的more命令非常的不同,我们自己编写的more并没有等待我们输入命令,而是一溜烟全部显示出来了,那么到底是什么问题呢?
其实很简单,问题出在getchar这个函数上,这个函数是从标准输入中获取字符的,然而,我们ls命令的输出已经重定向到标准输入了,意味着getchar和ls共用一个数据流,所以我们自己编写的more命令才会没有等待我们输入命令,而一下子全部打印了出来。
关于流,网上有很多解释,我看了但是依旧不是太理解,我自己画了一个图,也表达了我对流的理解,一个文件与另一个文件进行数据的传输,我认为这就是一个流。共用一个流就是两个文件都与一个文件同时传输数据。
![](/assets/blank.gif)
这下找到了问题的根源,也就是说getchar不适用与more命令中,我们需要更改more。意味着我们需要把getchar的输入换成一个独立的流,
more命令的编写---版本2
1 #include <stdio.h>2 #include <stdlib.h>3 4 #define PAGELEN 245 #define LINELEN 5126 7 void do_more(FILE *);8 int see_more(FILE *);9
10 int main(int ac,char *av[])
11 {
12
13 FILE *fp;
14 if(ac == 1)
15 do_more(stdin);
16 else
17 while(--ac)
18 if((fp = fopen(* ++av,"r")) != NULL)
19 {
20 do_more(fp);
21 fclose(fp);
22 }
23 else
24 exit(1);
25
26 return 0;
27 }
28
29
30 void do_more(FILE *fp)
31 {
32 char line[LINELEN];
33 int num_of_lines = 0;
34 int reply;
35 FILE *fp_tty;
36 fp_tty = fopen("/dev/tty","r");
37 if(fp_tty == NULL)
38 exit(1);
39
40 while(fgets(line, LINELEN,fp))
41 {
42 if(num_of_lines == PAGELEN)
43 {
44 reply = see_more(fp_tty);
45
46 if(reply == 0)
47 break;
48
49 num_of_lines -= reply;
50 }
51 if(fputs(line,stdout) == EOF)
52 exit(1);
53
54 num_of_lines++;
55 }
56 }
57
58 int see_more(FILE *cmd)
59 {
60 int c;
61 printf("\033[7m more?\033[m");
62 while((c = getc(cmd)) != EOF)
63 {
64 if(c == 'q')
65 return 0;
66 if(c == ' ')
67 return PAGELEN;
68 if(c == '\n')
69 return 1;
70
71 }
72 return 0;
73 }
第二个版本中使用了 /dev/tty 这个设备文件,向这个文件写相当于显示在用户的屏幕上,向这个文件读相当于从键盘中获取用户输入。这样我们的程序就拥有两个流, “ls” 的输出,将其分页显示到屏幕上,当more需要用户输入时,从 /dev/tty得到数据。
第二个版本仍然有more字符被打印到输出上、按下空格或者Q键还需要额外按下回车、无法根据中断大小来决定显示行数、无法文件已显示的百分比,这些问题有涉及到与终端类有关,我暂时读到这里,以后慢慢补充
-----------------上文在 2019/4/30 记录-------------------
本篇笔记自拜读《 Unix/Linux编程实践教程》
我也推荐和我一样的初学者去拜读这本书,让你对linux有可下手的地方。
Linux---more命令学习相关推荐
- linux基础命令学习笔记(二)
linux基础命令学习笔记(二) 1.kill :终止进程 kill pid (唯一标示一个进程) kill -9 强制终止 kill -15 命令未结束不能终止 # ps aux 查看所有进程 ...
- linux账户密码 群组放在,linux基础命令学习(四)用户与群组
一.linux用户账号的管理 linux用户账号的管理主要包括用户添加.用户删除.用户修改. 添加用户账号就是在系统创建一个新账号,然后为新账号分为用户号.用户组.主目录和登录Shell等资源. 刚添 ...
- Linux基础命令学习——方法二(给swap分区增加500M)
在之前的博客中也有相关介绍,将Swap分区扩展500M,当然有很多方法,今天来记录第二种方法. 上篇介绍swap分区扩展500M的方法: Linux基础命令学习--实战篇(给swap分区增加500M) ...
- linux命令cp建立硬链接,Linux cp命令学习
linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命 ...
- 【Linux学习】Linux free 命令学习
一.学习这个命令的背景 因为最近Gitlab服务器占用内存很多,也在下面的这篇博客里面写了怎么减少Gitlab占用的内存问题. +[Git学习]解决GitLab内存消耗大的问题 但是一开始并没有很清楚 ...
- (初学入门足够)Linux终端命令学习——在VMware虚拟机中创建的ubuntu(Linux最常用的发行版本)
目录 前言 学习Linux终端命令的原因 学习Linux终端命令的技巧 Linux常用命令 一.常用linux命令的基本使用 1.查看目录内容 1.1 ls 列表和隐藏文件显示 1.2 ls 通配符的 ...
- Linux dmesg 命令学习
/proc文件系统 在 /proc 文件系统中,对虚拟文件的读写操作是一种与内核通信的手段,要查看内核回环缓冲区中的消息,可以使用 dmesg 工具(或者通过 /proc 本身使用 cat / ...
- linux (ubuntu) 命令学习笔记
1, md5sum 输出字符串的MD5值 echo -n 123456 | md5sum //-n表示不打印回车符 2, ubuntu设置dock任务栏鼠标点击效果 16.04: 调整位置:gsett ...
- Linux常用命令学习大全
Linux常用命令大全 窍门:Ctrl+F 快速查找Linux命令(为了方便查看,下面的每个标题都可以点击收缩) Linux命令 - 系统信息 命令代码 注释说明 arch 显示机器的处理器架构(1) ...
- Linux 常用命令 学习笔记
1.创建目录: //创建目录filetest mkdir filetest 2.创建子目录: //创建子目录filetestchild mkdir -p filetest/filetestchild ...
最新文章
- iOS UITextField输入框随键盘弹出界面上移
- Java中集合中根据对象的某个属性去重
- 动手学PaddlePaddle(5):迁移学习
- linux的基础知识——会话
- python 连续三个数满足条件_计算满足条件的连续值数(Pandas Dataframe)
- ServiceComb中的数据最终一致性方案
- 2022年企业微信生态研究报告
- 查看 linux 网络状态命令,Linux操作系统常用的网络状态查询命令
- 科学计算机的用途,计算机最主要的用途之一就是科学计算,科学计算可分为两类...
- Linux下autoconf与automake
- 快速在指定文件夹打开命令行
- 学计算机的是不是都非常木讷,北大学神韦东奕​是正常人吗?内向木讷是缺点​,拿不出手?​...
- Python进行vivo手机评论数据信息情感分析、LDA主题分析
- Java @Min(0)的意义
- 滚动轴承损伤、偏翘、电蚀、跑外圈特征分析及信号特征提取
- 学习深度学习是否要先学习机器学习?
- CSS:设置边框和背景
- Day-8 bootstrap 徽章、进度条、分页、列表组
- 破解flashFXP密码全过程
- Javascript 元素拖曳操作 By shawl.qiu (兼容IE,Opera,Firefox)
热门文章
- 晶圆测试中的pinforce
- 神经网络注意力机制可视化,人工神经网络可视化
- Unity Shader 学习笔记(27)渲染轮廓线(描边)方法、卡通风格渲染、素描风格渲染
- 台湾大学林轩田《机器学习基石》学习笔记第6讲——Theory of Generalization
- 书柜板子厚度如何去选择
- EXCEL 将列内容,逆序粘贴
- 运维和网工的差别,跟你们说一说
- 【文件缺失/被隐藏】三种递进式方法寻找文件(有点新奇)、丢失文件填补方法(etc/host文件‘丢失’为例)
- LeetCode_962_Maximum Width Ramp
- Java中POJO、VO、DTO、PO、Entity的区别