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 列出目录所有文 ...
随机推荐
- Hadoop Ecosystem related ports
本文总结了Hadoop生态系统中各个组件使用的端口,包括了HDFS,Map Reduce,HBase,Hive,Spark,WebHCat,Impala,Alluxio,Sqoop等,后续会持续更新. ...
- 06-struts2与ognl的结合
1 参数接收 2 配置文件中 1 Demo2Action package www.test.c_config; import com.opensymphony.xwork2.ActionSupport ...
- Git~分支真的很轻
轻,让人觉得很爽 所有源代码管理工具都有管理分支的功能,git当然也不例外,而且git的分支是非常轻的,不像tfs,svn那样,复制一大堆代码,git只记录变化的内容,有本地分支与远程分支之分,原则上 ...
- [Scala] Currying
Currying是一種函數式編程技巧, 指的是把接受多個參數的函數變換成接受一個單一參數的函數. 以一個簡單的例子在Scala中實現.. def f(a:Int, b:Int)={ a+b } //f ...
- 查询指定tomcat应用的进程数
假设应用名称为pear,查询指定tomcat应用pear的进程数: ps -ef |grep "/datong/tomcat-pear/" |grep -v tail | grep ...
- BNU4286——Adjacent Bit Counts——————【dp】
Adjacent Bit Counts Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Jav ...
- 在nginx上部署django项目--------Gunicorn+Django+nginx+mysql
一.安装nginx 以前的博客我有写,这里就不写了 http://www.cnblogs.com/wt11/p/6420442.html 二.安装mysql 我用的mysql5.7 64位的二进制包 ...
- 11、幻灯片:Slides
/* ---ts----*/ import { Page,Slides } from 'ionic-angular'; import { ViewChild } from '@angular/core ...
- ASP .NET SVN && emmet 插件
学习 ASP .NET 时间的第三周: 来讲讲如何在 visual studio 2013...上搭载 SVN吧: 废话不多说: One Step: 电脑上已安装 visual studio 201 ...
- Android设备之间通过Wifi通信
之前写过PC与Android之间通过WIFI通信(通过Socket,可以在博客里面搜索),PC作为主机,Android作为客户机,现在手头有一台仪器通过wifi传输数据,如果仪器作为主机发射WIFI热 ...