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用户对于自己所用资源的软限制可以升高可以降低但高也不能高过自己的硬限制,对于自己的硬限制则可以升高可以降低。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构和算法-树和二叉树的定义和基本术语和性质

文章目录 树的基本概念和相关术语相关的应用节点间的关系描述节点,树的属性描述有序树vs无序树树vs森林小结 树的相关性质考点1考点2考点3考点4考点5考点6小结 二叉树的相关概念和基本术语重要 (五种状态)特殊二叉树小结 二叉树的相关性质二叉…

SpringCloudAlibaba之Nacos的持久化和高可用——详细讲解

目录 一、Nacos持久化 1.持久化说明 2.安装mysql数据库5.6.5以上版本(略) 3.修改配置文件 二、nacos高可用 1.集群说明 2.nacos集群架构图 2.集群搭建注意事项 3.集群规划 4.搭建nacos集群 5.安装Nginx 6.配置nginx conf配置文件 7.启动nginx进行测试即可 一、Nacos持久…

【算法】NOIP2003神经网络

题目描述 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的…

经验分享:JMeter控制RPS

一、前言 ​ RPS (Request Per Second)一般用来衡量服务端的吞吐量,相比于并发模式,更适合用来摸底服务端的性能。我们可以通过使用 JMeter 的常数吞吐量定时器来限制每个线程的RPS。对于RPS,我们可以把他理解为我们的TPS,我们就…

19.Oracle11g中的游标

oracle11g中的游标 一、案例引入二、什么是游标三、隐式游标1、隐式游标的属性2、创建语法3、示例 四、显示游标1、显示游标的属性2、创建语法3、示例 五、REF游标1、REF游标的属性2、创建语法3、示例 六、循环游标1、 循环游标的作用2、用for 与 loop 创建3、示例 一、案例引入…

基于可微分渲染器的相机位置优化【PyTorch3D】

在这个教程中,我们将使用可微渲染学习给定参考图像的相机的 [x, y, z] 位置。 我们将首先使用相机的起始位置初始化渲染器。 然后,我们将使用它来生成图像,使用参考图像计算损失,最后通过整个管道进行反向传播以更新相机的位置。…

【开源】基于Vue+SpringBoot的企业项目合同信息系统

项目编号: S 046 ,文末获取源码。 \color{red}{项目编号:S046,文末获取源码。} 项目编号:S046,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 合同审批模块2.3 合…

Flask Echarts 实现历史图形查询

Flask前后端数据动态交互涉及用户界面与服务器之间的灵活数据传递。用户界面使用ECharts图形库实时渲染数据。它提供了丰富多彩、交互性强的图表和地图,能够在网页上直观、生动地展示数据。ECharts支持各种常见的图表类型,包括折线图、柱状图、饼图、散点…

FFmepg 核心开发库及重要数据结构与API

文章目录 前言一、FFmpeg 核心开发库二、FFmpeg 重要数据结构与 API1、简介2、FFmpeg 解码流程①、FFmpeg2.x 解码流程②、FFmpeg4.x 解码流程 3、FFMpeg 中比较重要的函数以及数据结构①、数据结构②、初始化函数③、音视频解码函数④、文件操作⑤、其他函数 三、FFmpeg 流程1…

【活动回顾】sCrypt在柏林B2029开发者周

B2029 是柏林的一个区块链爱好者、艺术家和建设者聚会,学习、讨论和共同构建比特币区块链地方。 在2023年6月9日至11日,举行了第7次Hello Metanet研讨会。本次研讨会旨在为参与者提供一个学习、讨论和共同构建比特币区块链的平台。 在这个充满激情和创意…

C语言:输出所有“水仙花数”。“水仙花数”是指一个3位数,其各位数字的立方和等于该数本身,如153=1^3 +5^3+3^3

分析: 在主函数 main 中,程序首先定义四个整型变量 m、a、b 和 c,并用于计算和判断水仙花数。然后使用 printf 函数输出提示信息。 接下来,程序使用 for 循环结构,从 100 到 999 遍历所有三位数。对于每个遍历到的数 m…

Vue简易的车牌输入键盘,可以根据需要修改

效果图如下&#xff1a; 代码如下&#xff1a; <template><div><div class"carNoBoxInput"><div style"padding: 6px;border: 2px solid #fff;border-radius: 6px;margin: 6px 3px 6px 6px;"><input class"inputBox"…

Make sure bypassing Vue built-in sanitization is safe here.

一、问题描述 二、问题分析 XSS(跨站脚本攻击) XSS攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法注入恶意指令代码到网页&#xff0c;使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript&#xff0c;但实际上也可以包括J…

https到底把什么加密了?

首先直接说结论&#xff0c; https安全通信模式&#xff0c;是使用TLS加密传输所有的http协议。再重复一遍&#xff0c;是所有&#xff01; 通常将TLS加密传输http这个通信过程称为https&#xff0c;如果使用协议封装的逻辑结构来表达就是&#xff1a; IP TCP TLS 【 HTTP 】…

大连大学2023年11月程序设计竞赛(同步赛)

B、爆wa种子!&#xff08;数学&#xff09; 一、题目要求 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 爆wa种子发现了上次玩游戏时你和妙wa种子的py交易&#xff0c;所以他要求这次玩游戏你来当爆wa种子的枪手&#xff0c;为他写个程序…

前端 --- HTML

目录 一、网络的三大基石 ​二、什么是HTML 一、HTML 指的是超文本标记语言 二、HTML的作用 三、HTML的标准结构 四、IDE_HBuilder的使用 一、编码工具&#xff1a; 二、集成开发环境 三、HBuilder使用步骤&#xff1a; 五、HTML的标签的使用 一、html_head_body 二、head…

CSS新手入门笔记整理:CSS字体样式

字体类型&#xff1a;font-family 语法 font-family&#xff1a;字体1,字体2,...,字体n; font-family可以指定多种字体。使用多个字体时&#xff0c;将按从左到右的顺序排列&#xff0c;并且以英文逗号&#xff08;,&#xff09;隔开。如果我们不定义font-family&#xff0c…

viple模拟器使用(三):unity模拟器中实现沿右墙迷宫算法

沿右墙迷宫算法 引导 线控模拟可以使得通过用户手动操作&#xff0c;实现机器人在模拟环境下在迷宫中行走&#xff08;即&#xff1a;运动&#xff09;&#xff0c;算法可以使得机器人按照一定的策略自动行走&#xff0c;沿右墙迷宫算法就是其中的一种策略。 目的 运行程序后&…

Scrapy框架内置管道之图片视频和文件(一篇文章齐全)

1、Scrapy框架初识&#xff08;点击前往查阅&#xff09; 2、Scrapy框架持久化存储&#xff08;点击前往查阅&#xff09; 3、Scrapy框架内置管道 4、Scrapy框架中间件&#xff08;点击前往查阅&#xff09; Scrapy 是一个开源的、基于Python的爬虫框架&#xff0c;它提供了…

3D模型纹理集合并【Python|C#】

使用 Substance Painter 时&#xff0c;将模型的各个部分分成不同的纹理集非常有用。 这可以帮助遮罩&#xff0c;或者只是保持层栈干净。 不幸的是&#xff0c;Painter 无法将多个纹理集中的所有贴图导出为单个图集&#xff0c;即使在创建单独对象的 UV 时考虑到了这一点。 显…