Linux学习日记
01.教你使用系统调用手写cat指令
文章开始之前,先介绍几个指令
编译
cc demo.c -o demo
这样在当前目录下编译出一个可执行文件 demo
执行
./demo
若想直接 demo
来执行程序,因为在 $PATH
中没有当前目录, 所以系统不认识 demo
。所以要用 ./
来指定当目录。也可以将当前目录添加入 $PATH
中。(但不建议这样使用哦)
$PATH=.:$PATH #因为$PATh中的文件路径是由:连接的
[root@localhost c]# echo $PATH
/usr/local/maven/apache-maven-3.9.5/bin:/usr/local/jdk/jdk1.8.0_381/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
编写myCat.c文件
首先想想cat的作用,cat的就是读取文件然后打印在控制台上,cat 文件名
,那只要我们的程序能打开文件、读取文件、打印读取内容即可。
首先在当前目录创建myCat.c,然后开始正式编写,以以下步骤进行。
1.打开文件
我们可以使用man指令来查看文档。一开始不知道使用什么系统调用,只知道是打开文件的系统调用,那么这个系统调用的名字应该与open有关,那么可以使用man的检索功能:
man -k open | grep \(2 #在man手册中,系统调用是第二章,\是转义字符
输出如下:
[root@localhost c]# man -k open|grep \(2
creat (2) - open and possibly create a file or device
flock (2) - apply or remove an advisory lock on an open file
mq_open (2) - open a message queue
name_to_handle_at (2) - obtain handle for a pathname and open file via a handle
open (2) - open and possibly create a file or device
open_by_handle_at (2) - obtain handle for a pathname and open file via a handle
perf_event_open (2) - set up performance monitoring
epoll_create (2) - open an epoll file descriptor
epoll_create1 (2) - open an epoll file descriptor
openat (2) - open a file relative to a directory file descriptor
可以看到open指令。
使用man查看open系统调用的文档 man 2 open
:
OPEN(2) Linux Programmer's Manual
NAME
open, creat - open and possibly create a file or device
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
DESCRIPTION
Given a pathname for a file, open() returns a file descriptor, a small, nonnegative integer for use in subsequent system calls (read(2), write(2), lseek(2), fcntl(2), etc.). The file descriptor
returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.
......
现在进入myCat文件,将查到的open系统调用的头文件、系统调用用上
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//ac是参数的个数,av是字符串数组,因为指令为`cat 文件名`,所以有两个参数
main(int ac,char *av[]){
int fd;
if(ac<2){
printf("USE:CMD FILENAME");
exit(1);
}
if((fd=open(av[1],O_RDONLY))==-1){ //O_RDONLY是打开文件的模式,类似于c语言打开文件函数的r,具体的参数可以使用上面的man 2 open查看
perror("Cannot open");
exit(-1);
}
printf("%d\n",fd);
}
在这段代码中,open系统调用返回的fd是什么意思呢?这就与linux操作系统有关:
说明:
每一个进程都有一个打开文件表,记录着每一个被当前进程打开的文件的信息(打开方式、读写指针等等)。fd就是当前进程这个文件在打开文件表中的索引。
2.读取文件、打印读取内容
怎么找读取文件文档的步骤和第一步一样,就不多赘述了。
READ(2) Linux Programmer's Manual
NAME
read - read from a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
编写myCat.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
main(int ac,char *av[]){
int fd;
int n;
char buf[1024];
if(ac<2){
printf("USE:CMD FILENAME");
exit(1);
}
if((fd=open(av[1],O_RDONLY))==-1){
perror("Cannot open");
exit(-1);
}
printf("%d\n",fd);
while((n=read(fd,buf,sizeof(buf)))>0){
printf("%.*s",n,buf);
};
}
以上,myCat已经编写完毕,运行试试!!!
3.运行
到myCat.c的目录中
编译:
cc myCat.c -o myCat
执行:
./myCat /usr/include/stdio.h
看到打印内容就是成功了。
以上,myCat已经编写完毕,运行试试!!!
以上是本人在课上学习到的内容,如有错误请指出!!!