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
#include <stdio.h>
#include <stdlib.h> #define PAGELEN 24
#define LINELEN 512 void do_more(FILE *);
int see_more(); int main(int ac,char *av[])
{ FILE *fp;
if(ac == )
do_more(stdin);
else
while(--ac)
if((fp = fopen(* ++av,"r")) != NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(); return ;
} void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines = ;
int see_more(),reply; while(fgets(line, LINELEN,fp))
{
if(num_of_lines == PAGELEN)
{
reply = see_more(); if(reply == )
break; num_of_lines -= reply;
}
if(fputs(line,stdout) == EOF)
exit(); num_of_lines++;
}
} int see_more()
{
int c;
printf("\033[7m more?\033[m");
while((c = getchar()) != EOF)
{
if(c == 'q')
return ;
if(c == ' ')
return PAGELEN;
if(c == '\n')
return ; }
return ;
}
fopen 打开文件,打开成功返回一个指向该文件的文件指针,失败返回NULL。
fgets 从指定的文件中获取数据,每次读一行,并存入指定的buffer中最多读size - 1个
fputs 把字符串输出到stram中,但不输出空字符。发生错误,则输出EOF
getchar 从标准输入获取一个字符,相当于getc(stdin)
more版本1的问题:
1.当屏幕上的文字上滚时,[ more ]字符也会随之上滚,

2.当我们按下空格或者 "q" 后,如果没有按下回车,程序没有任何反应。
自己编写的more命令分析
我们首先使用linux自带的more命令
$ ls /bin | more
很明显,我们想做的是将/bin 目录下的文件分页显示,在使用 “ | ”管道命令把 ls 的输出重定向到 more的输入,并且等待我们输入命令,结果是令人满意的。
我们再使用自己编写的more命令
$ls /bin | more_v1
发现和linux自带的more命令非常的不同,我们自己编写的more并没有等待我们输入命令,而是一溜烟全部显示出来了,那么到底是什么问题呢?
其实很简单,问题出在getchar这个函数上,这个函数是从标准输入中获取字符的,然而,我们ls命令的输出已经重定向到标准输入了,意味着getchar和ls共用一个数据流,所以我们自己编写的more命令才会没有等待我们输入命令,而一下子全部打印了出来。
关于流,网上有很多解释,我看了但是依旧不是太理解,我自己画了一个图,也表达了我对流的理解,一个文件与另一个文件进行数据的传输,我认为这就是一个流。共用一个流就是两个文件都与一个文件同时传输数据。

这下找到了问题的根源,也就是说getchar不适用与more命令中,我们需要更改more。意味着我们需要把getchar的输入换成一个独立的流,
more命令的编写---版本2
#include <stdio.h>
#include <stdlib.h> #define PAGELEN 24
#define LINELEN 512 void do_more(FILE *);
int see_more(FILE *); int main(int ac,char *av[])
{ FILE *fp;
if(ac == )
do_more(stdin);
else
while(--ac)
if((fp = fopen(* ++av,"r")) != NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(); return ;
} void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines = ;
int reply;
FILE *fp_tty;
fp_tty = fopen("/dev/tty","r");
if(fp_tty == NULL)
exit(); while(fgets(line, LINELEN,fp))
{
if(num_of_lines == PAGELEN)
{
reply = see_more(fp_tty); if(reply == )
break; num_of_lines -= reply;
}
if(fputs(line,stdout) == EOF)
exit(); num_of_lines++;
}
} int see_more(FILE *cmd)
{
int c;
printf("\033[7m more?\033[m");
while((c = getc(cmd)) != EOF)
{
if(c == 'q')
return ;
if(c == ' ')
return PAGELEN;
if(c == '\n')
return ; }
return ;
}
第二个版本中使用了 /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常用命令学习4---(挂载命令mount umount、用户登陆查看和用户交互命令 w who last lastlog)
紧接着上一篇Linux的命令行的学习:Linux学习3---(文件的压缩和解压缩命令zip unzip tar.关机和重启命令shutdown reboot……) 1.挂载命令 简介 ...
- 【Linux】命令学习笔记和总结
莫名的想学习一下Linux了,因为对这方面的知识储备为0.对于命令行界面始终是零接触零了解,对一个程序员来说这几乎是致命的,所以简单了解一下. 一.教程参考 参考菜鸟教程即可: Linux 教程 | ...
- Linux常用命令学习
1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...
- linux sort命令学习
linux sort命令以行为单位对文本文件进行排序. 接下来我们会以/tmp/sort_test.txt这个文本文件为例对sort命令的用法进行说明. sh-# cat /tmp/sort_test ...
- linux source命令学习
1. linux source命令的作用? 我们可能经常需要修改到诸如/etc/profile,~/.bash_profile等这样的配置文件, 一方面我们希望所作的修改在当前的环境中立即生效: 另一 ...
- linux (ubuntu) 命令学习笔记
1, md5sum 输出字符串的MD5值 echo -n 123456 | md5sum //-n表示不打印回车符 2, ubuntu设置dock任务栏鼠标点击效果 16.04: 调整位置:gsett ...
- linux基础命令学习(六)文件的特殊属性
Linux chattr命令用于改变文件属性. 这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下8种模式: a:让文件或目录仅供附加用途. b:不更新文件或目录的最后存取 ...
- 五个知识体系之-Linux常用命令学习
1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...
- Linux常用命令学习随笔
1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...
随机推荐
- TT8509: PL/SQL execution terminated; PLSQL_TIMEOUT exceeded
TT8509: PL/SQL execution terminated; PLSQL_TIMEOUT exceeded plsql_timeout连接超时,解决办法: ODBC pl/sql选项卡 修 ...
- ife task0001页面实现细节问题总结
好久没写css了,突然对重构页面陌生了许多.不过也没什么,前面几个月一直扩充知识面,偏重了理论技术学习,结果还不算遗憾.昨天重拾css,针对问题做点总结: 一.语义化方面 1.HTML5新标签使用 标 ...
- vim创建新的命令
转自:http://man.chinaunix.net/newsoft/vi/doc/usr_5F40.html#usr_40.txt *40.1* 键映射 简单的映射已经在 |05.3| 介绍过了. ...
- tomcat-dbcp数据库连接池配置以及使用时候的一些坑
一.数据库连接池 开发的时候经常会需要对数据库进行一些操作,比如说常见的增删改查之类的,当数据量小的时候,可以直接进行操作,但是当数据量增多的时候,每一次连接以及释放数据库都会耗费一定的时间,这个时候 ...
- 深入理解JavaScript系列(36):设计模式之中介者模式
介绍 中介者模式(Mediator),用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 主要内容来自:http://www ...
- Java原生隐藏字符-工具类
package com.seesun2012.common.util; /** 隐藏字符-工具类 @author seesun2012@163.com */ public class HiddenCh ...
- Hashtable(哈希表)
简体字繁体字转化: class Program { static void Main(string[] args) { Hashtable ht = new Hashtable(); ; i < ...
- Wpf ListView展示风格
ListView数据绑定控件,通常是竖列展示,也可以通过改变ListView的布局来改变它的展示方式 如图展示: 主要需用修改的样式如下: <!--GridView Header样式 去除Gri ...
- C#学习笔记9
1.多播委托:由与delegate关键字声明的委托,在编译后默认继承Delegate与MulticastDelegate类型,所以声明的委托自然就含有多播委托的特性,即一个委托变量可以调用一个方法链( ...
- OLEDB 数据变更通知
除了之前介绍的接口,OLEDB还定义了其他一些支持回调的接口,可以异步操作OLEDB对象或者得到一些重要的事件通知,从而使应用程序有机会进行一些必要的处理.其中较有用的就是结果集对象的变更通知接口.通 ...