unix/linux学习笔记:chapter1

时间:2022-01-24 10:33:23
  1. 容纳操作系统的内存空间叫做系统空间,容纳应用程序的内存空间叫做用户空间

  2. 系统资源:处理器,输入输出,进程管理,内存,设备,计时器,进程间通信,网络

  3. (1)它能做什么? ·分析程序」
    (2)它是如何实现的? ·学习系统调用」
    (3) 能不能自己写一个? ·编程实现」

  4. unix能做些什么?
    (用户角度):登录(一个用户有一个shell进程,有这个进程来处理用户的请求),运行程序,注销,目录操作,文件操作,文件权限
    (系统角度):通信,协作,网络访问

  5. date:日期 fortune: 随机出现一个诗句

  6. ls , cd , pwd , mkdir , rmdir

  7. cat,more,less,pg –查看文件内容 , cp , rm , mv , lpr(打印文件) , lp

  8. bc:计算器,可以处理很大的数,可编程的(类似C语言语法),(内部通过调用真正的计算机dc来实现,bc是dc的预处理器,类似于浏览器与服务器的关系)


more01.c

#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==1)
do_more(stdin);
else
while(--ac)//有ac个文件,轮流处理
{
if((fp=fopen(*++av,"r"))!=NULL)//只读方式打开地文件
{
do_more(fp);//成功打开一个文件则进行处理处理
fclose(fp);
}
else
exit(1);//不成功打开则退出
}
return 0;
}

void do_more(FILE *fp)//处理文件的函数
{
char line[LINELEN];//缓冲区
int num_of_lines=0;屏幕中已显示的行数
int see_more(),reply;

while(fgets(line,LINELEN,fp)){//从文件中欧你读取一行,读到文件结束符则退出
if(num_of_lines==PAGELEN){//从0开始,如果已输出的行数等于24
reply=see_more();//则停止输出,等待用户输入命令getchar()
if(reply==0)
//如果see_more()返回值是0则推出,(输入了q或终止信号)
break;
num_of_lines-=reply;//已输出行数减少一行,继续读取文件
}
if(fputs(line,stdout)==EOF)
exit(1);
num_of_lines++;//每显示一行自增1
}
}

int see_more()//输出满 PAGELEN 行后等待处理用户的命令
{
int c;
printf("\003[7m more? \003[m");//在最低行输出提示信息
while((c=getchar())!=EOF)//获取用户输入的命令
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}

存在的问题:

(1) 最低端的旧的提示信息more? 会随着屏幕向上滚
(2) 按下空格键或‘q’后需要按回车程序才会继续执行
(3) 执行命令 ls /bin | ./more01 ,结果并不是我们想象的会每24行,分页显示,而是一次性将 ls /bin 所有的结果输出

第三个问题原因是: 管道 | 已经将more01的标准输入重定向到了标准输出,而more01使用getchar() ,它是从标准中读取数据的,所以ls /bin 将结果直接作为more01的输入,没有用户的什么事。

解决这个问题的办法就是:
(1)从标准输入中获取要分页的数据;
(2)从/dev/tty获取用户的输入

/dev/tty是显示器和键盘的设备描述文件,向这个文件写入数据会输出到显示器,而从中读取会从键盘中读取


more02.c

#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==1)
do_more(stdin);
else
while(--ac)
if((fp=fopen(*++av,"r"))!=NULL)
{
do_more(fp);
fclose(fp);
}
else
exit(1);
return 0;
}
void do_more(FILE *fp)
{
char line[LINELEN];
int num_of_lines=0;
int see_more(),reply;

FILE *fp_tty;
fp_tty=fopen("/dev/tty","r");//键盘和显示器的文件描述符
if(fp_tty==NULL)
exit(1);

while(fgets(line,LINELEN,fp)){
if(num_of_lines==PAGELEN){
reply=see_more(fp_tty);//参数
if(reply==0)
break;
num_of_lines-=reply;
}
if(fputs(line,stdout)==EOF)
exit(1);
num_of_lines++;
}
}
int see_more(FILE *cmd)
{
int c;
printf("\003[7m more? \003[m");
while((c=getc(cmd))!=EOF)//输入来源是键盘getc(cmd),而不是getchar()
{
if(c=='q')
return 0;
if(c==' ')
return PAGELEN;
if(c=='\n')
return 1;
}
return 0;
}