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

news2024/11/26 0:41:06

目录和文件

获取文件属性

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

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.coloradmin.cn/o/1260160.html

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

相关文章

ubuntu 下载编译 opencv4.2.0并检验

如有帮助点赞收藏关注! 如需转载,请注明出处! ubuntu 的opencv4.2.0下载与编译 下载依赖开始编译安装配置OpenCV编译环境检验* 完成 下载 首先下载opencv源码网址: https://opencv.org/releases/page/3/ 下载成zip后,…

GPIO的使用--操作PF09 PF10 PF08实现呼吸灯、跑马灯、警报闪烁灯

先来个呼吸灯演示 呼吸灯 目录 一、GPIO的介绍 1.含义 2.控制原理 3.控制流程 二、LED控制 1.呼吸灯 操作代码 烧录结果 2.蜂鸣器红绿灯交替 操作代码 3.红绿灯交替闪烁 操作代码 一、GPIO的介绍 1.含义 GPIO(general porpose intput output),通用输入输出端口。…

Java游戏 王者荣耀

GameFrame类 所需图片: package 王者荣耀;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList…

分布式事务-两阶段提交2PC

2PC协议就是两阶段提交,用来解决分布式事务,分为两个阶段,分别为Prepare和Commit,也是PC由来。 第一阶段Prepare 提交事务请求 如图所示,主要流程有以下三个方面 询问:事务协调者(Manager)向所有的事务参与…

SpringBoot : ch06 整合 web(二)

前言 SpringBoot作为一款优秀的框架,不仅提供了快速开发的能力,同时也提供了丰富的文档和示例,让开发者更加容易上手。在本博客中,我们将介绍如何使用SpringBoot来整合Web应用程序的相关技术,并通过实例代码来演示如何…

C++值常用集合算法

C值常用集合算法 set_intersection #include<iostream> using namespace std; #include<vector> #include<numeric> #include<algorithm>class MyPrint { public:void operator()(int val){cout << val<<" ";} };void test() {v…

电力感知边缘计算技术网关产品设计方案-硬件方案

网关硬件架构设计图: 1.配置方案 配置差异 A类网关 B类网关 CPU

Postman接口测试 —— 设置断言和集合运行

一、常见的5种断言方法 Postman是一款非常强大的API接口调式工具&#xff0c;它自带断言方法&#xff0c;不需要学习JavaScript脚本&#xff0c;非常方便。 &#xff08;1&#xff09;Status code&#xff1a;Code is 200(校验接口返回结果的状态码) &#xff08;2&#xff09…

室内定位(WiFi/UWB/蓝牙等)技术方案概述

室内无法搜索到卫星&#xff0c;这样常规的GPS/北斗定位都无法使用&#xff0c;常规免费的只有运营商的基站定位LBS&#xff0c;但这个精度实在太差&#xff0c;一般都有几十米到几百米的偏差。因此&#xff0c;室内定位一直是个老大难问题。 截至目前&#xff0c;业界比较成熟…

C++:对象模型和this指针

对象模型&#xff1a; 成员变量和成员函数分开存储 在C中&#xff0c;类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 空对象占用空间&#xff1a; 1字节 C编译器会给每个空对象也分配一个字节空间&#xff0c;是为了区分空对象占内存的位置 每个…

ESP32网络开发实例-Web页面控制直流电机

Web页面控制直流电机 文章目录 Web页面控制直流电机1、应用介绍2、软件准备3、硬件准备4、代码实现在这个 ESP32 Web务器应用中,我们将创建一个托管在 ESP32 上的网页,我们将使用该网页来控制使用 L298N 电机驱动器模块的直流电机的速度。 网页将包含一个 HTML 滑块,用于为直…

web:[NPUCTF2020]ReadlezPHP

题目 打开页面显示如下 没发现其他的线索&#xff0c;查看源代码 发现一个网址&#xff0c;访问这个页面查看 进行代码审计 这段代码是一个简单的 PHP 类&#xff0c;名为 HelloPhp。它有两个公共属性 $a 和 $b&#xff0c;并在构造函数中将它们分别初始化为字符串 "Y-m-…

第四节HarmonyOS 熟知开发工具DevEco Studio

一、设置主体样式 默认的代码主题样式是黑暗系的&#xff0c;如下图所示&#xff1a; 如果你不喜欢&#xff0c;可以按照一下步骤进行修改&#xff1a; 左上角点击Flie->Settings->Appearance&Behavior->Appearance&#xff0c;点击Theme&#xff0c;在弹出的下拉…

【TinyALSA全解析(三)】tinyplay、tincap、pcm_open源码解析

tinyplay、tincap、pcm_open源码解析 一、本文的目的二、tinyplay.c源码分析三、tinycap.c源码分析四、pcm.c如何调度到Linux Kernel4.1 pcm_open解析4.1.1 pcm_open的主要流程4.1.2 流程说明4.1.3 调用方法 4.2 pcm_write解析 /*********************************************…

土壤类型数据技术服务

一.背景介绍 土壤质地类型不同表明各地土壤表层内具有不同的矿质颗粒大小分布特点&#xff0c;而不同的颗粒大小分布特点又具有不同的辐射传输、水分平衡、热量平衡等特点。因此&#xff0c;土壤质地类型资料可广泛应用于土壤资源评价、土壤肥力估计、大气热力学及动力学方程等…

心大数据结构题型

选择题 2021 数据处理的单位&#xff1a;数据元素 矩阵压缩存储 2022 ①单链表头插法选择 ②矩阵压缩存储&#xff0c;行优先 ③删除链表节点的时间复杂度 ④稀疏矩阵存储 ⑤平衡二叉树时间复杂度 ⑥栈和队列的出队&#xff0c;问栈的大小至少多少 ⑦拓扑排序 ⑧参考书 360…

Qt_一个由单例引发的崩溃

Qt_一个由单例引发的崩溃 文章目录 Qt_一个由单例引发的崩溃摘要关于 Q_GLOBAL_STATIC代码测试布局管理器源码分析Demo 验证关于布局管理器析构Qt 类声明周期探索更新代码获取父类分析Qt 单例宏源码 关键字&#xff1a; Qt、 Q_GLOBAL_STATIC、 单例、 UI、 崩溃 摘要 今…

每日一题--寻找重复数

蝶恋花-王国维 阅尽天涯离别苦&#xff0c; 不道归来&#xff0c;零落花如许。 花底相看无一语&#xff0c;绿窗春与天俱莫。 待把相思灯下诉&#xff0c; 一缕新欢&#xff0c;旧恨千千缕。 最是人间留不住&#xff0c;朱颜辞镜花辞树。 目录 题目描述&#xff1a; 思路分析…

SpringCloud-高级篇(五)

一&#xff1a;分布式事务理论基础 原子性&#xff08;Atomicity&#xff09; 原子性是指事务是一个不可分割的工作单位&#xff0c;事务中的操作要么都发生&#xff0c;要么都不发生。 一致性&#xff08;Consistency&#xff09; 事务前后数据的完整性必须保持一致。 隔离性&…

生物神经系统的基本原理 神经元Neuron

生物神经系统的基本原理涉及一系列复杂的生物学和生理学机制&#xff0c;主要可以分为以下几个方面&#xff1a; 神经元与突触&#xff1a;神经系统的基本单位是神经元&#xff0c;它们通过突触连接彼此。神经元接收并处理来自身体其他部分或环境的信息&#xff0c;然后通过电信…