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命令学习的更多相关文章

  1. linux基础命令学习笔记(二)

    linux基础命令学习笔记(二) 1.kill :终止进程  kill pid (唯一标示一个进程) kill -9  强制终止  kill -15 命令未结束不能终止 # ps aux 查看所有进程 ...

  2. Linux常用命令学习4---(挂载命令mount umount、用户登陆查看和用户交互命令 w who last lastlog)

    紧接着上一篇Linux的命令行的学习:Linux学习3---(文件的压缩和解压缩命令zip unzip tar.关机和重启命令shutdown reboot……) 1.挂载命令     简介      ...

  3. 【Linux】命令学习笔记和总结

    莫名的想学习一下Linux了,因为对这方面的知识储备为0.对于命令行界面始终是零接触零了解,对一个程序员来说这几乎是致命的,所以简单了解一下. 一.教程参考 参考菜鸟教程即可: Linux 教程 | ...

  4. Linux常用命令学习

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  5. linux sort命令学习

    linux sort命令以行为单位对文本文件进行排序. 接下来我们会以/tmp/sort_test.txt这个文本文件为例对sort命令的用法进行说明. sh-# cat /tmp/sort_test ...

  6. linux source命令学习

    1. linux source命令的作用? 我们可能经常需要修改到诸如/etc/profile,~/.bash_profile等这样的配置文件, 一方面我们希望所作的修改在当前的环境中立即生效: 另一 ...

  7. linux (ubuntu) 命令学习笔记

    1, md5sum 输出字符串的MD5值 echo -n 123456 | md5sum //-n表示不打印回车符 2, ubuntu设置dock任务栏鼠标点击效果 16.04: 调整位置:gsett ...

  8. linux基础命令学习(六)文件的特殊属性

    Linux chattr命令用于改变文件属性. 这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下8种模式: a:让文件或目录仅供附加用途.    b:不更新文件或目录的最后存取 ...

  9. 五个知识体系之-Linux常用命令学习

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  10. Linux常用命令学习随笔

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

随机推荐

  1. URL篇之不安全字符处理

    URL是可移植的.它要统一命名因特网上的所有资源,就需要通过各种不同的协议来传送这些资源.这些协议在传输数据时会使用不同的机制,所以,设计URL,使其可以通过任意因特网协议安全地传输是很重要的. UR ...

  2. fastclick.js源码解读分析

    阅读优秀的js插件和库源码,可以加深我们对web开发的理解和提高js能力,本人能力有限,只能粗略读懂一些小型插件,这里带来对fastclick源码的解读,望各位大神不吝指教~! fastclick诞生 ...

  3. 《springcloud 四》服务保护机制

    服务保护机制SpringCloud Hystrix 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用 ...

  4. 解决eclipse中org.w3c.dom.Node类老报The method getTextContent() is undefined 问题

    http://www.cnblogs.com/itspy007/articles/4431581.html

  5. Linux下安装配置MongoDB数据库

    说明: 操作系统:CentOS 5.X 64位 IP地址:192.168.21.130 实现目的: 安装配置MongoDB数据库 具体操作: 一.关闭SElinux.配置防火墙 1.vi /etc/s ...

  6. mavne 工程jsp页面首行报错

    在pom.xml文件中加入servlet依赖 <dependency> <groupId>javax.servlet</groupId> <artifactI ...

  7. java常用API之字符串缓冲区

    StringBuffer类: StringBuffer是个字符串的缓冲区,是可变的字符串数组,即就是它是一个容器,容器中可以装很多字符串.并且能够对其中的字符串进行各种操作 StringBuffer的 ...

  8. flex布局帮助你快速实现布局

    flex布局可以帮我们快速布局一些区块,实现你想要的效果,不用再去float,position之类的.我们在布局网页的时候很多时候都是一些特殊布局,flex就能帮我快速去布局,不需要去定位. 任何一个 ...

  9. 闭包中的this

    var name="pushline";//全局变量 var obj=new Object(); obj.name="jms"; obj.getName=fun ...

  10. 正则表达式备忘录-Regular Expressions Cheatsheet中文版

    正则表达式备忘录Regular Expressions Cheatsheet中文版原文:https://www.maketecheasier.com/cheatsheet/regex/ 测试文件a.t ...