Linux基础 文件和目录
文件和目录
前言
本章讨论文件属性和文件系统内容。除了上一章讨论的普通文件,Linux的文件概念还包括:目录、设备等。在Linux系统中,文件的种类包括:普通文件、目录、符号链接、块设备、字符设备、管道、套接字。
本章讨论的主要内容为普通文件、目录和符号链接。它们的公共特点是,真实的保存在了硬盘中,而其它类型的文件是内核产生的文件,在硬盘中并不存在。
文件属性
通过stat函数或者stat命令可以获得文件属性。
文件属性 | 解释 |
---|---|
dev_t st_dev | 设备号 |
ino_t st_ino | inode编号 |
mode_t st_mode | 访问权限相关 |
nlink_t st_nlink | 硬链接数量 |
uid_t st_uid | 拥有该文件的用户 |
gid_t st_gid | 拥有该文件的组 |
dev_t st_rdev | 设备号 |
off_t st_size | 文件尺寸 |
blksize_t st_blksize | 文件系统的IO尺寸 |
blkcnt_t st_blocks | 占用的block数量,一个block为512字节 |
time_t st_atime | 最后访问时间 |
time_t st_mtime | 最后修改时间 |
time_t st_ctime | 最后文件状态修改时间 |
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> int main()
{
struct stat buf;
int ret = stat(".", &buf);
if(ret < 0)
{
perror("stat");
return 0;
} if(S_ISREG(buf.st_mode))
{
printf("this is regular file\n");
}
else if(S_ISDIR(buf.st_mode))
{
printf("this is dir\n");
} // 测试拥有该文件的账户是否有读权限
if(S_IRUSR & buf.st_mode)
{
printf("user can read\n");
} open("a.txt", O_CREAT|O_RDWR, 0777); // access("./a.out", R_OK|W_OK|X_OK); printf("file size is %d\n", (int)buf.st_size);
getchar();
return 0;
}
3.3 文件类型
在前言中,提到文件类型包括七种,在stat结构题中,保存了文件的文件类型属性,它的文件类型属性保存在st_mode中。但是七种类型,只需要3位即可,而st_mode是一个整数,因此它还保存其它内容,如果需要判断一个文件属于何种类型,需要一些宏的帮助。
文件类型属性是只读的属性,无法修改。
3.4 用户和组
Linux是一个多用户操作系统,因此每个文件都有属性,记录着这个文件属于哪个用户/组。
用户/组信息可以被修改,可以通过chown来修改文件所属的用户和组信息。
修改文件所属用户和组,需要root权限。
新文件所属用户和组,是创建该文件的进程所属用户和组。
实际账户和有效账户
账户 | 解释 |
---|---|
实际账户 | 登陆系统时的账户 |
有效账户 | 决定进程的访问资源的账户 |
3.5 文件访问权限
文件使用了9个位来表示访问权限,和文件类型一起,保存在st_mode中。此9位分成3组,每组3个位,分别表示读/写/执行权限,而三个组分别表示拥有该文件的账户,拥有该文件的组,其它用户组的权限。如果对应位是1,表示有权限,如果是0表示没有权限。
1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
---|
文件访问权限经常用8进制来表示,比如上表的权限位可以表示为0755,意思是拥有它的账户对这个文件有读/写/执行权限,而拥有它的组有读/执行权限,其它账户对它有读/执行权限。
Linux提供一些宏,来测试文件的权限位
可以通过access函数来测试程序是否有访问某文件的权限。
创建文件时,可以指定文件的访问权限位,但是会收到umask位影响。
可以通过chmod来修改文件的权限位
3.6 其它权限位
3.6.1 SUID
只能对文件设置,如果文件设置了该位,那么该文件被运行时,对应的进程的权限,不是运行该程序账户的权限,而是拥有该用户的权限。
在对文件
未设置SUID的情况下:
如果对文件
设置了SUID,那么:
可以通过chmod u+s
或者chmod u-s
来设置获取去除SUID。
设置SUID可以让一个普通账户拥有它不该有的权限,容易产生安全漏洞。
3.6.2 SGID
可以对文件和目录设置,如果对文件设置,那么它的作用类似SUID,不过影响的是组。
如果对目录设置,那么拷贝到该目录下的文件都会被置位,除非拷贝是带
-p
参数。 在Ubuntu下测试并不如此。
在Ubuntu下设置了目录的SGID之后,在那个目录下创建的文件,拥有者是有效账户,而拥有组是该目录的拥有组。
命令:chmod g+s
chmod g-s
3.6.3 StickyBit
可以对文件或者目录设置,如果对文件设置,那么当这个文件运行并退出后,系统依旧保留该文件对应的映象,这样这个程序再次运行时,就不需要加载再加载了。这个属性的作用并不大,因为它占用了内存。
如果对目录设置,那么表示在该目录下,账户只能删除和修改它自己创建的文件,对于其它账户创建的文件,它不能修改和删除。这个位作用比较大,在一些公共目录,往往有这个属性,比如/tmp
命令:chmod o+t
chmod o-t
总结:
位 | 设置对象 | 设置方法 | 查看 | 效果 |
---|---|---|---|---|
SUID | 文件 | chmod u+s | 如果用户执行权限位为s或者S,则表示SUID有设置 | 当该文件被执行时,进程所拥有的权限是拥有该文件的账户权限 |
SUID | 目录 | 不可设置 | ||
SGID | 文件 | chmod g+s | 如果组执行权限位为s或者S,则表示GUID有设置 | 当执行该文件时,进程所属组是该拥有该文件的组 |
SGID | 目录 | chmod g+s | 同上 | 在该目录中创建文件时,该文件的所属组是目录的所属组 |
StickyBit | 文件 | chmod o+t | 如果其他执行权限位为t或者T,那么该文件有设置StickyBit | 执行该文件并退出后,系统保留该文件占用的一些内存,以便加快下一次的加载运行 |
StickyBit | 目录 | chmod o+t | 同上 | 账户只能修改和删除该目录下属于该账户的文件,不能修改该目录下其他账户创建的文件 |
3.7 文件长度
st_size保存文件的长度,write函数会修改该属性,也可以通过truncate修改文件大小,truncate可以扩大文件或者缩小文件,缩小文件时,文件内容会被删减。
文件大小可以通过ls
,wc -c
,stat
命令获取。
也可以通过fseek
和ftell
函数配合获取,或者直接通过stat
函数获取文件长度。
3.8 文件系统
3.8.1 文件管理
文件系统描述文件在硬盘中的组织,保存在硬盘中的文件只有普通文件、目录、软链接。
为了更加方便的管理持久性文件存储,操作系统一般对硬盘进行有规划的管理,规划包括:
分区
格式化
文件系统指一个分区内,文件存储的组织方式。
在Linux下,通过mount命令将分区挂载到虚拟文件系统。
3.8.2 inode
一个硬盘分区,被格式化之后,可以认为硬盘被划分成两部分:管理数据和数据。管理数据部分保存着这个分区的分区信息,以及inode表。
inode保存文件的属性信息,stat命令能看到的信息,大部分都是保存在inode里的,一个inode占用128或者256字节,这个依赖具体的文件系统,每当在硬盘上创建一个文件/目录时,系统为这个文件/目录分配一个inode。值得注意的是,文件名,不存在inode中,而是存在文件所在目录的文件内容部分。
3.8.3 数据块
数据部分被简单的、按照等大尺寸的划分成n块,一般每块数据块的尺寸为1024-4096,由具体文件系统决定。
3.8.4 文件
当创建一个文件时,系统为该文件分配一个inode。如果往该文件写数据,那么系统为该文件分配数据块,inode会记录这个数据块位置,当一个数据块不够用时,系统会继续为它分配数据块。
3.8.5 目录
当创建一个目录时,系统为该目录分配一个inode,同时分配一个数据块,并且在该数据块中,记录文件.
和..
对应的inode。
如果在该目录下创建文件newfile
,那么参考上一节内容,会为该文件创建inode,最后将newfile
文件名和它的inode,作为一条记录,保存在目录的数据块中。
如果一个inode被别人引用,那么它的引用计数器会加1。
3.8.6 路径和寻址
Linux系统采用以/划分的路径字符串来寻址文件。
比如命令mkdir testdir
,寻址和操作过程如下图:
思考:为什么mv命令很快,而cp命令很慢,rename如何实现的
补充:分区
查看磁盘信息
磁盘名字 sda sdb ..
分区名字 sda1 sda2 ...
分区
n 创建新分区
p 输出分区信息
w 保存分区信息并退出
分区和挂载
挂载成功之后,对xxyy目录的读写,其实是在/dev/sdb1文件系统中。
开机自动挂载
通过mount挂载的目录是临时的。如果希望开酒就挂载,那么可以将挂载命令写入到/etc/profile。或者修改/etc/fstab文件,/etc/fstab描述了开机需要挂载的文件系统信息。
去除挂载
通过手动umount去除挂载。
3.8.7 硬链接和软链接
硬链接不占用inode,只占用目录项。
软链接占用inode。
创建链接命令ln,硬链接只将对应的inode在目录总增加一个名字,并且将inode的引用计数器+1。
为了可以跨文件系统和对目录进行链接,创建了软链接这种方式。ln -s
思考:为什么硬链接不能跨文件系统,而且不能对目录进行硬链接
3.8.8 虚拟文件系统VFS
内存无法加载硬盘所有内容,因为一般内存比硬盘小,但是在Linux内核中,维护了一个虚拟文件系统,将硬盘的目录结构映射到内存中。这个映射一般只包含已经被打开的文件。
3.9 文件删除
使用unlink命令和函数可以删除一个文件。
如果此时文件已经打开,那么该文件也可以被unlink,但是删除操作不会立即执行,而会被保留到文件关闭时执行。
3.10 文件时间
对文件的访问,会导致文件时间发生变化。系统会自动记录用户对文件的操作的时间戳,以便将来可以查询文件修改时间。
如果需要故意修改,那么可以通过utime函数,修改文件的访问时间和修改时间。
touch
命令也可以将文件的时间修改为当前时间。touch
命令的副作用是,如果参数所指文件不存在,那么创建一个空文件。
当用户进行大规模拷贝时,cp
操作会修改文件的访问时间,如果想提高效率,可以使用-p
选项,避免文件属性的修改,同时加快速度。
#include <sys/types.h>
#include <utime.h> int main()
{
struct utimbuf buf;
buf.actime = 0;
buf.modtime = 0;
utime("a.out", &buf);
}
利用utime来修改文件的访问时间和修改时间
3.11 目录操作
3.11.1 创建和删除目录
mkdir
和rmdir
3.11.2 遍历目录
opendir
,closedir
,readdir
,rewinddir
,telldir
,seekdir
遍历目录
seekdir和telldir
#include <dirent.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h> int main(int argc, char* argv[])
{
DIR* dir = opendir(argv[1]);
struct dirent* entry; while(1)
{
entry = readdir(dir);
if(entry == NULL)
break; // linux下,.开头是隐藏文件
if(entry->d_name[0] == '.')
continue; printf("%s\n", entry->d_name);
} closedir(dir);
}
3.12 练习
3.12.1 实现文件拷贝,保留文件属性
3.12.2 实现目录打包到文件,将文件解包成目录
3.13 函数和命令
3.13.1 函数
stat/lstat:查看文件属性
chmod:修改文件权限
chown:修改文件的所有者
utime:修改文件时间
unlink:删除文件
link:创建硬链接
symlink:创建软链接
rmdir:删除空目录
mkdir:创建空目录
opendir:打开目录
closedir:关闭目录
readdir:读取一个目录项,并且将目录项指针移到下一项
seekdir:修改目录项指针
rewainddir:重置目录项指针
telldir:获得当前目录向指针
判断权限位宏 S_IRUSR(stat.st_mode)
判断文件类型宏S_ISDIR(stat.st_mode)
3.13.2 命令
stat:查看文件属性
chmod:修改文件权限
chown
unlink:删除文件(不会跟随)
ln:创建链接
mkdir
rmdir
rm
cp
dd:拷贝数据(可以拷贝文件,也拷贝块设备)
wc:计算文件内容的行数、单词数、字节数
which:查找非内置的命令位置
fdisk:查看磁盘信息、分区
mkfs:在分区中创建文件系统(ext2,ext3,ext4, fat32, ntfs, xfs,nfs)
mount:挂载
umount:取消挂载
Linux基础 文件和目录的更多相关文章
- Linux基础--文件与目录管理
1.目录与路径 1)特殊目录 . 代表此层目录 .. 代表上一层目录 - 代表前一个工作目录 ~ 代表『目前使用者身份』所在的家目录 ~account 代表account这个使用者的 ...
- (五)Linux之文件与目录管理以及文本处理
Linux之文件与目录管理 目录 Linux之文件与目录管理 前言 绝对路径与相对路径说明: 一.目录常用命令 常用处理目录的命令: 切换目录 cd 显示当前路径 pwd 查看目录下文件 ls 创建目 ...
- [转]Linux中文件权限目录权限的意义及权限对文件目录的意义
转自:http://www.jb51.net/article/77458.htm linux中目录与文件权限的意义 一.文件权限的意义 r:可以读这个文件的具体内容: w:可以编辑这个文件的内容,包括 ...
- Linux之文件、目录
Linux之文件.目录 文件权限 User.Group.Others 在Linux中,任何一个文件都具有这三种身份的个别权限,三者的区别是 User: 指每一个单独的用户,例如member1,memb ...
- Linux命令——文件和目录管理
Linux命令--文件和目录管理 基本命令 命令ls 作用:显示目录下的文件和文件夹 说明:默认显示当前目录,可跟路径参数 参数:-a,显示隐藏目录 参数:-l,显示文件权限 参数:-d,显示文件最后 ...
- tar---打包,解压缩linux的文件和目录
tar命令可以为linux的文件和目录创建档案.利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar最初被用来在磁带上创建档案,现在,用户可以在 ...
- Linux 基础-文件权限与属性
一,文件类型 1.1,概述 1.2,正规文件(regular file) 1.3,目录(directory) 1.4,链接文件(link) 1.5,设备与装置文件(device) 1.6,资料接口文件 ...
- Linux改变文件或目录的访问权限命令
使用 ll 或 ls -l 指令时 第一列会显示出目录下文件的权限 例如∶ -rw-r-r- 横线代表空许可.r代表只读,w代表写,x代表可执行.注意这里共有10个位置.第一个字符指定了文件类型 ...
- linux命令——scp 两台linux机器间文件或目录传输
不同的Linux之间copy文件常用有3种方法: 第一种:ftp,也就是其中一台Linux安装ftpServer,这样可以另外一台使用ftp的client程序来进行文件的copy. 第二种:采用sam ...
随机推荐
- Python(一)转义字符及操作符
转义字符 描述 \(在行尾时) 续航符 \\ 反斜杠符号 \' 单引号 \'' 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 转行 \v 纵向制表符 \t 横向 ...
- Java问题之超过数值表示范围(例如64位)结果是什么 (阶乘)
关于老师在课上所提及的这个问题 我做了验证 截图如下 只是一个简单的计算阶乘的代码 在运行时得到了如下结果 可以看到,对于部分数字如果超出范围会从64位处自动截断,而这时由于是二进制表示,首位默认是符 ...
- 重写 hashcode()真有那么简单嘛?
万万没想到一个 hashcode() 方法,既然会引出一堆的知识盲区,简直了. 起因: 老八股:为什么重写Equals方法要重写HashCode方法. 大声告诉我为什么,闭着眼睛先把答案背出来,啥?这 ...
- jsp页面重定向后地址栏controller名重复而导致报404错误
今天做ssm项目时遇到了这种错误 看看代码: 无关代码省略... 22 <body> 23 <div id="container"> 24 <ifra ...
- hyperf-搭建初始化
官方文档* https://hyperf.wiki/2.0/#/README 初步搭建1. 安装项目 composer create-project hyperf/hyperf-skeleton 2. ...
- JavaScript中的代码执行顺序
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head&g ...
- 2022最新版超详细的Maven下载配置教程、IDEA中集成maven(包含图解过程)、以及导入项目时jar包下载不成功的问题解决
文章目录 1.maven下载 2.maven环境变量的配置 3.查看maven是否配置成功 4.配置文件的修改 5.IDEA集成maven 6.导入项目时jar包下载不成功的问题解决 maven教程: ...
- vulnhub靶场之THALES: 1
准备: 攻击机:虚拟机kali.本机win10. 靶机:THALES: 1,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub.com/th ...
- 第2-1-5章 docker安装MinIO实现文件存储服务-springboot整合minio-minio全网最全的资料
目录 1. MinIO介绍 2. MinIO应用场景 2.1 单主机单硬盘模式 2.2 单主机多硬盘模式 2.3 多主机多硬盘分布式 3. MinIO特点 4. 存储机制 5. docker安装Min ...
- JUC学习笔记——共享模型之内存
JUC学习笔记--共享模型之内存 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍: Java内存模型 可见性 模式之两阶段终止 模式之Balk ...