Linux系统编程:文件系统总结

目录和文件

获取文件属性

获取文件属性有如下的系统调用,下面逐个来分析。
在这里插入图片描述

stat:通过文件路径获取属性,面对符号链接文件时获取的是所指向的目标文件的属性

从上图中可以看到stat函数接收一个文件的路径字符串(你要获取哪个文件的属性),还有一个stat类型的结构体指针的缓冲区,然后我们所需要的该文件的属性全都会保存在这个stat类型结构体的缓冲区buf中,我们要查看的话通过使用这个缓冲区即可查到。

下面来具体看一下stat结构体的定义:
在这里插入图片描述
我们接下来来简单的使用一下这个系统调用,这个程序用来查看某个文件的大小:
在这里插入图片描述

在这里插入图片描述
可以看见正常输出,同理stat结构体内定义了的属性都是可以直接使用的。

fstat: 通过文件描述符获取属性

lstat: 面对符号链接文件时获取的是符号链接文件的属性

文件访问权限

文件访问权限的内容全部都在stat结构体中的 st_mode这个属性中,st_mode是一个十六位的位图,用于表示文件类型、文件访问权限及特殊权限位。

在man手册中我们可以看到对于文件权限这一块,Linux给我们提供了对应的宏来实现对文件的判断:
在这里插入图片描述

举一个例子:
在这里插入图片描述
在这里插入图片描述
除了上述这种宏的形式外,文件权限还有一个对应的位图,但这里不展开论述(我的Ubuntu系统中手册没有对应的说明,也有可能是我没找到,但是宏定义的形式已经够用啦)。

umask

我们之前说过,如果在终端上创建文件,假如没特意设定其权限值的话,那么将会产生一个默认的权限,这就是因为有umask的存在才导致的,其求权限公式是:在这里插入图片描述

其中0666是系统默认先赋予的(前提是我们没指定),然后将umask的值按位取反后,二者相与最后得到这个新文件的最终权限。

使用umask可以得到当前系统的umask值:
在这里插入图片描述
使用umask 后跟四个位的数字可以更改这个值,但重启终端之后又会恢复原样。

umask这种机制的存在,就是为了防止产生权限过于松散的文件。

这个命令实际上也是一个系统调用:
在这里插入图片描述
这就不再演示,看文档就能明白。

文件权限的更改/管理:chmod,fchmod

这两个也是系统调用,并非是我们终端上所使用的命令嗷:
在这里插入图片描述
也比较简单,不再赘述。

粘住位

粘住位也叫 t 位,其一开始的作用是给一个可执行的二进制的命令设置一个当前 t 位,就是把某一个命令的使用痕迹给保留下来,为了在下一次装载这个模块的时候调用比较快。

比如有的命令常用,那么就在内存当中保存它的使用痕迹,下次调用就比较快。

但是随着技术革新现在这一点不需要了,现在常用这个 t 位来对某一个目录进行设置:
在这里插入图片描述
可以看见tmp目录的权限的最后一位就是 t 位。

这就意味着各个用户对该目录以及该目录下的文件进行操作时就会有点特殊化了。

这里了解一下即可。

文件系统:FAT、UFS(二者都是Unix系统早期的文件系统,后者开源前者不开源)

文件系统:就是用来解决文件或者数据的存储格式和管理等问题。
关于这个老师也只是讲了概述性质的内容,感兴趣可以自己去找点资料看,这里不再赘述。

硬链接与符号链接

硬链接与符号链接的关系以及二者是什么就不赘述了,主要提一下和这两个东西相关的系统调用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另外注意:硬链接与目录项是同义词,且建立硬链接有限制:不能给分区建立,不能给目录建立。

符号链接优点:可跨分区,可以给目录建立。

时间相关更改命令:utime

在这里插入图片描述
可以看出utime系统调用修改的是文件最后一一次读写的时间。

上面的第二个参数就是一个结构体参数utimbuf,其定义在上图的下方,可以看到我们通过该结构体可以对access time(最后读的时间)和modification time(最后写的时间)进行修改(比较少用啦)。

后面我们还有个专题专门来讲解时间这部分。

目录的创建和销毁

在这里插入图片描述
在这里插入图片描述

更改当前工作路径

在这里插入图片描述

分析目录/读取目录内容

这一节的内容我们需要使用到递归,可以用两种方式实现,一种是直接使用glob函数:
在这里插入图片描述
我们来写个小例子详细解释一下这个函数的使用,这个例子程序的作用是查看某个目录下面以a开头的.conf文件有多少:
在这里插入图片描述
在这里插入图片描述
还有一种是使用一大堆函数来堆叠使用达到相同的效果,opendir、closedir、readdir、rewinddir、seekdir、telldir:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么我们依然可以写一个小例子程序来进行一个练习,这个程序用来描述/etc文件目录下共有多少文件:
在这里插入图片描述

目录解析实例(一)

实现du功能:
在这里插入图片描述
du指令的功能就是以字节为单位来显示当前路径下所有文件所占的K数,比如上面第一个例子就表示fileSystem目录就占36KB大小的数据。

为什么要用到递归呢?
在这里插入图片描述
如上图所示,若要展示的文件目录下还有子目录也一并会打印出来,那么肯定是要使用递归来查询所有的内容。

那么接下来我们来实现这个功能:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

系统数据文件和信息

/etc/passwd

在这里插入图片描述

打开该文件:
在这里插入图片描述
这个文件详细记录了系统的用户信息、组信息以及一些其它的系统数据等等,具体可以参考APUE这本书,这里不再赘述,只介绍跟这个有关的几个函数:

getpwuid() 和 getpwnam()

在这里插入图片描述
这两个函数都是通过给定的参数比如用户名或者用户id返回其对应的用户信息,用户信息会放在一个passwd的结构体中:
在这里插入图片描述
也就是可以获取上述的信息。
例子程序:
在这里插入图片描述

在这里插入图片描述

/etc/group

一样,先打开看一下这个文件:
在这里插入图片描述
这个顾名思义就是和用户组相关的信息都在这个文件里面,和上面说的类似,也有两个函数:

getgrgid() 和 getgrgrnam()

在这里插入图片描述
和之前类似,结构体group的定义如下:
在这里插入图片描述
例子程序就不再赘述。

/etc/shadow

这个文件叫阴影文件,里面存放了一些口令信息,是非常重要且隐私的文件。
在这里插入图片描述
在这里插入图片描述
因为这个内容比较隐私,所以就不放图了。
但和之前的内容一样,会提到几个函数:

getspnam() 和 getspent() 以及crypt()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结构体spwd的定义如下:
在这里插入图片描述
crypt是加密函数,其man手册描述如下:
在这里插入图片描述
其中phrase是原串也就是原文,setting就是加密的方式,然后这个函数返回一个被加密了的字符串。

一个简单的加密程序:

在这里插入图片描述
在这里插入图片描述
shadow文件注意一定要使用root用户来进行操作嗷,这里我没用root权限所以执行不了,不再赘述。

时间戳

之前提到过,stat系统调用下有个关于time_t的时间类型(这好像是红帽系列的Linux是time_t类型,我用的Ubuntu,所以有点不不太一样好像):
在这里插入图片描述
在这里插入图片描述
关于这一块,我们需要掌握下面几个函数:
time()、gmtime()、localtime()、mktime()、strftime()。

time()

在这里插入图片描述
其作用是以秒为单位获取时间,其用法如下:
在这里插入图片描述
这个stamp可以作参数也可以直接作返回值,因为效果是一样的,从man手册中可以看出来。

gmtime() 和 localtime()

在这里插入图片描述
结构体tm的定义如下:
在这里插入图片描述

gmtime很明显就是将一个time_t类型的时间戳转换成tm类型的结构体,同理localtime也是一样不再赘述。

mktime()

这个函数实际上是上面两个函数的逆向过程:
在这里插入图片描述
将结构体tm又逆向回一个time_t类型。

strftime()

在这里插入图片描述
这个函数的作用是格式化时间和日期,其作用是将一个tm结构体(第四个参数)当中提出来我所需要的结构体字段(第三个参数),然后把这个字段放到由第一个参数和第二个参数所构成的缓冲区中(s是字符串,max就是最大字节数)。

第三个参数格式在man手册中有对应的操作,下图中的%a等就是第三个参数所需要的格式字符串:
在这里插入图片描述
简单的使用:
在这里插入图片描述

时间专题实例

程序一,实现类似下面内容的输出,每一秒输出一次带行号:
在这里插入图片描述

程序如下:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
再来一个示例程序,该程序用来求从现在开始一百天后是哪一天:
在这里插入图片描述
在这里插入图片描述

进程环境

注意目前还是讲的单进程内容。

main函数

main函数本身就是一个进程或者说线程,在后面会再提及。

进程的终止(正常终止和异常终止)

正常终止:

从main函数返回,如return 0;
调用exit;
调用_exit或者_Exit;
最后一个线程从其启动例程返回;
最后一个线程调用pthread_exit;

return 0和 exit(0)有什么区别?
返回 return 0 表示是给当前这个进程的父进程看的,这是一个约定俗成的写法,没有什么特别的说法,而exit则是一个函数(钩子函数):
在这里插入图片描述
可以看见exit函数可以引发进程的正常终止,与之相关的还有一个函数是atexit()钩子函数(onexit函数与其类似,但atexit用的比较多):
在这里插入图片描述
当进程正常终止时这个atexit()函数会被调用。

我们写一个小例子来感受一下:
在这里插入图片描述

在这里插入图片描述

而_exit和_Exit则是系统调用,也就是说上面的exit函数是依赖于这二者的:
在这里插入图片描述
那么与exit有什么区别呢?

exit函数被调用时会直接将整个程序的执行步骤全部执行,比如钩子函数该调的调用,缓冲区该刷新的刷新,那么此时如果是程序出了问题的情况我们还是调用exit函数退出的话,就很可能会将本来的小错误给扩大化(因为影响了后面钩子函数啊、缓冲区中的内容,造成了一步错步步错的效果),所以此时肯定不能使用exit,为了阻止错误进一步扩散,我们可以使用_exit或者_Exit,这两个函数就不会去执行后面的步骤而是直接退出,或者使用abort信号也行。

剩下部分的解析都涉及信号的内容,这些会在后面说到,这里不再赘述。

异常终止:

调用abort;
接到一个信号并终止;
最后一个线程对其取消请求做出响应;

异常终止和正常终止的情况非常重要,必须要熟记。

命令行参数的分析

这一块内容涉及两个函数:getopt() 和 getopt_long(),一个接收命令行短格式一个接收长格式。
在这里插入图片描述
接下里我们使用 getopt() 函数来实现一个小程序,可以根据命令行输入 -m 表示获得现在是几月, -h 表示现在是几点, -y表示现在是几年等等:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述

环境变量

main函数在最开始的时候其实有三个参数,其中第三个参数就是环境变量。
环境变量的本质其实就是:KEY = VALUE;
查看环境变量,使用export命令:
在这里插入图片描述
可以看到我们使用的很多命令在环境变量里面都是有的,这是我们能够在shell窗口下很便捷的使用各种命令的原因(因为如果不是这样的话我们就得写很长的命令串)。
比如 ls 命令就在PATH环境变量里,使用ls命令时shell就会去PATH里面寻找 ls 命令的二进制可执行文件并执行。

PATH环境变量所保存的二进制可执行文件就叫Shell 的外部命令处理,也就是说这类文件是存储在磁盘上的,我们能找到它并对它进行调用。内部命令处理就是OS自带的,比如进程调度啊、管道啊之类的。

在这块会用到一个值叫 environ ,它相当于一个全局变量,被用来保存所有环境变量的内容。
它存放的形式非常像main函数中的 argv[] 参数数组,是一个二维数组,其中每一行是一个字符串,我们写个小例子来看一下:
在这里插入图片描述

在这里插入图片描述

关于环境变量我们需要知道的几个函数:getenv()、setenv()、putenv();
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

C程序的存储空间布局

在这里插入图片描述
可以使用 pmap 命令来查看一个进程在当前系统下的内存分布情况:
在这里插入图片描述
当我们将位于各区内的代码都写在一个c文件中并运行时,通过 pmap 指令就能知道其各个变量会被存放在哪个区了,这是一个很好的学习方法。

使用 ps axf 可以以一个树状结构来查看当前系统中的所有进程以及进程父子关系:
在这里插入图片描述

函数跳转

这里不是说通常意义上的调用函数之后就跳转到另一个函数了,这里强调的是在不改变现有数据结构的情况下实现函数的跳转。
比如递归这种操作,递归的本质就是压栈,那么若此时一个函数位于栈顶想调用栈底的函数怎么办呢?goto语句也只能实现在函数内部的跳转,我们需要类似于goto这样的机制来实现在各个函数间进行跳转,所以又有几个函数需要学习:
setjmp() 和 longjmp();

setjmp函数是用来设置跳转点的,longjmp函数是用来进行从某个位置跳回到某个跳转点的。

这两个函数可以进行安全的跨函数跳转。

来试一下:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
可以看见现在是正常的函数之间的调用。

现在加入跳转函数,先来看一下跳转函数的man手册定义:
在这里插入图片描述
在这里插入图片描述
如果是在设置跳转点,那么返回值就是0,如果是从别处跳回来,那么返回值就为非0。

接下来我们将在上面的程序中,让函数 d 跳走,然后在函数 a 当中设置一个跳转点:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
可以看见直接跳转到了函数 a,然后程序直接执行结束了就。

资源的获取及控制

查看系统资源的命令还记得吗?
ulimit -a:
在这里插入图片描述

这里依然是提供两个函数,一个是getrlimit()用来获取资源总量,另外一个是setrlimit()用来设置资源总量。

在这里插入图片描述
在这里插入图片描述
可以从上图看到有个硬限制和软限制,软限制表示其只能在硬限制范围内活动,高不能高过硬限制;普通用户对自己某种资源的硬限制只能降低不能抬高,而对于root用户对于自己所用资源的软限制可以升高可以降低但高也不能高过自己的硬限制,对于自己的硬限制则可以升高可以降低。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/174786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十三章 解析PR曲线、ROC曲线、AUC、AP(工具)

混淆矩阵Confusion Matrix 混淆矩阵定义 混淆矩阵是机器学习中总结分类模型预测结果的情形分析表,以矩阵形式将数据集中的记录按照真实的类别与分类模型预测的类别判断两个标准进行汇总。其中矩阵的行表示真实值,矩阵的列表示预测值,下面我…

file_get_contents() 函数详解与使用

概述 在PHP中,file_get_contents() 函数是一个强大的工具,它既可以用于读取本地文件的内容,也可以用于发起 HTTP 请求获取远程资源。本文将详细介绍 file_get_contents() 函数的两种主要用途,并探讨如何充分利用这个函数。 1. 文…

【高效开发工具系列】MapStruct入门使用

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

数据结构与算法编程题30

层次遍历二叉树(队列&#xff1a;先进先出) #define _CRT_SECURE_NO_WARNINGS#include <iostream> using namespace std;typedef char ElemType; #define ERROR 0 #define OK 1 #define Maxsize 100 #define STR_SIZE 1024typedef struct BiTNode {ElemType data;BiTNode…

Sringboot3 讲解

文章目录 前言一、Springboot快速入门1.1 实例1.2 总结&#xff1a;1.2.1 什么是starter启动器1.2.2 SpringBootApplication注解的功效 二、springboot3 统一配置文件1.概述2、属性配置文件使用简单案例3、yaml配置介绍和说明4、批量配置文件的读取5、多环境配置和激活 三、spr…

Netty I/O模型和线程模型

目录 1.概述 1.1 为什么使用Netty 1.2 Netty的优势 1.3 Netty的常见使用场景 2.Netty高性能的原因 2.1 I/O模型 2.1.1 阻塞IO 2.1.2 IO复用模型 2.2 线程模型 2.2.1 线程模型1&#xff1a;传统阻塞 I/O 服务模型 2.2.2 线程模型2&#xff1a;Reactor 模式 2.2.2.1 …

Javaweb之Vue组件库Element之Dialog对话框的详细解析

4.3.3 Dialog对话框 4.3.3.1 组件演示 Dialog: 在保留当前页面状态的情况下&#xff0c;告知用户并承载相关操作。其企业开发应用场景示例如下图所示 首先我们需要在ElementUI官方找到Dialog组件&#xff0c;如下图所示&#xff1a; 然后复制如下代码到我们的组件文件的templ…

线程基本方法

1。设置线程名 继承Thread类的线程&#xff0c;可以直接使用.setName()方法&#xff0c;设置线程名。也可以使用构造方法&#xff0c;需要注意java默认不继承构造方法&#xff0c;所以需要自己调用下父类的构造方法。 public class Demo {public static void main(String[…

每日一题:LeetCode-202.快乐数(一点都不快乐)

每日一题系列&#xff08;day 06&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

基于 Python中的深度学习:神经网络与卷积神经网络

当下&#xff0c;深度学习已经成为人工智能研究和应用领域的关键技术之一。作为一个开源的高级编程语言&#xff0c;Python提供了丰富的工具和库&#xff0c;为深度学习的研究和开发提供了便利。本文将深入探究Python中的深度学习&#xff0c;重点聚焦于神经网络与卷积神经网络…

csgo/steam搬砖项目还能不能做,分享玩法思路

饰品市场持续下跌&#xff0c;CSGO搬砖还有搞头吗&#xff1f; CSGO是最具竞争力的第一人称射击游戏。玩这款游戏离不开里面的炫酷配件。Steam搬砖项目是基于CSGO游戏中的配件运动。蒸汽拆砖项目的原理是使用国外Steam平台的充值卡购买国际服务器的配件和设备&#xff0c;然后转…

【C++】继承(下) 单继承 | 多继承 | 菱形继承 | 继承和组合

一、单/多/菱形继承 1.单继承 当一个子类只有一个直接父类时&#xff0c;称这个继承关系为单继承。 2.多继承 一个子类有两个或以上直接父类时称这个继承关系为多继承。 举个实例&#xff1a;新老师进学校工作时&#xff0c;一般会作为助教老师&#xff0c;一边代课教书&am…

古埃及金字塔的修建

从理论上说&#xff0c;古埃及人完全有能力设计并建造出充满各种奇妙细节的胡夫金字塔&#xff0c;但后世还是不断涌现出质疑之声&#xff0c;原因倒也简单&#xff0c;那就是胡夫金字塔实在太大了。据推算&#xff0c;整座金字塔使用大约230万块巨石&#xff0c;总质量可达约5…

通俗易懂的spring Cloud;业务场景介绍 二、Spring Cloud核心组件:Eureka 、Feign、Ribbon、Hystrix、zuul

文章目录 通俗易懂的spring Cloud一、业务场景介绍二、Spring Cloud核心组件&#xff1a;Eureka三、Spring Cloud核心组件&#xff1a;Feign四、Spring Cloud核心组件&#xff1a;Ribbon五、Spring Cloud核心组件&#xff1a;Hystrix六、Spring Cloud核心组件&#xff1a;Zuul七…

MySQL 8 手动安装后无法启动的问题解决

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;…

Dockerfile讲解

Dockerfile 1. 构建过程解析2. Dockerfile常用保留字指令3. 案例3.1. 自定义镜像mycentosjava83.2. 虚悬镜像 4. Docker微服务实战 dockerfile是用来构建docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 dockerfile定义了进程需要的一切东西&…

python之pyqt专栏6-信号与槽2

上一篇python之pyqt专栏5-信号与槽1-CSDN博客&#xff0c;我们通过信号与槽实现了点击Button&#xff0c;改变Label的文本内容。可以知道 信号是在类中定义的&#xff0c;是类的属性 槽函数是信号通过connect连接的任意成员函数&#xff0c;当信号发生时&#xff0c;执行与信号…

14 网关实战:网关聚合API文档

上节课介绍了网关层的认证鉴权,今天这节介绍一下网关层如何聚合API接口文文档。 为什么需要聚合API接口文档? 大型微服务系统模块众多,木谷博客系统就有9个,如果这些服务的接口地址没有一个统一,那么客户端将要保存每个服务的接口地址,这个肯定是不现实。 先来看一下A…

图书管理系统源码,图书管理系统开发,图书借阅系统源码四TuShuManager应用程序MVC控制器Controllers

Asp.net web应用程序MVC之Controllers控制器 Controller在ASP.NET MVC中负责控制所有客户端与服务器端的交互,并且负责协调Model与View之间的数据传递,是ASP.NET MVC的核心。 撰写Controller的基本要求: 1、Controller必须为公开类别; 2、Controller名称必须以Controller结…

【算法优选】 动态规划之路径问题——壹

文章目录 &#x1f38b;前言&#x1f38b;[不同路径](https://leetcode.cn/problems/unique-paths/)&#x1f6a9;题目描述&#xff1a;&#x1f6a9;算法思路&#xff1a;&#x1f6a9;代码实现 &#x1f38b;[不同路径二](https://leetcode.cn/problems/unique-paths-ii/desc…