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 列出目录所有文 ...
随机推荐
- (转)Shell——基本运算符
Shell 基本运算符 原文:http://blog.csdn.net/sinat_36053757/article/details/70319481 Shell 和其他编程语言一样,支持多种运算符, ...
- javascript遍历表
定义表结构 1. 通过id遍历 <html> <body> <table id="tb" border="1"> <t ...
- MVC设置默认页面
方法1:在RouteConfig.cs文件中配置默认路由 public class RouteConfig { public static void RegisterRoutes(RouteColle ...
- 了解WaitForSingleObject中WAIT_ABANDONED 返回值
1.互斥量内核对象 互斥量内核对象用来确保一个线程独占对一个资源的访问.互斥量对象包含一个使用计数.线程ID以及递归计数.互斥量与关键段的行为完全相同.但是互斥量是内核对象,而关键段是用户模式下的同步 ...
- 设计模式之职责链模式(JAVA实现)
学习netty框架时,看到有人说netty用到了设计模式的职责链模式,学习一下职责链模式,主要参考大话设计模式. 主要场景: 小菜想要加薪,向经理提出加薪请求,经理没有权限,经理交由总监处理,总监也没 ...
- vuex深入浅出
本文主要记录使用vuex的使用场景.重要组成部分和学习心得. 1.说在前面 学习vue有两周的时间了,目前已经对vue的基础使用比较熟悉了.但是一直对vuex的使用耿耿于怀,这么说是因为总是不太理解, ...
- composer 实用总结
1.在windows 下配置php环境变量 我电脑------右键属性-----高级系统设置-----环境变量---点击path----添加php.exe路径到环境变量 C:\phpStudy\php ...
- 【基础笔记】《html&CSS设计与构造网站》一书导读
◉HTML 1.结构网页使用HTML HyperText Markup Language 来描述页面结构超文本标记语言允许对文本建立链接,允许对文本进行标记网页开头都有一个DOCTYPE 文档类型 声 ...
- linux环境下安装jdk(本文示例是jdk1.6.0_45)
第一步:创建一个文件夹安装jdk(虽说地址一般自定义,但是为了方便查找请按照笔者建议目录 ):/usr/java 将jdk-6u45-linux-x64.bin文件放到 /usr/java 文件夹 ...
- (转)原生ajax的写法
1.创建XMLHttpRequest对象 function createXMLHTTPRequest() { //1.创建XMLHttpRequest对象 //这是XMLHttpReuquest对象无 ...