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+schmod g-s
3.6.3 StickyBit
可以对文件或者目录设置,如果对文件设置,那么当这个文件运行并退出后,系统依旧保留该文件对应的映象,这样这个程序再次运行时,就不需要加载再加载了。这个属性的作用并不大,因为它占用了内存。
如果对目录设置,那么表示在该目录下,账户只能删除和修改它自己创建的文件,对于其它账户创建的文件,它不能修改和删除。这个位作用比较大,在一些公共目录,往往有这个属性,比如/tmp
命令:chmod o+tchmod 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 ...
随机推荐
- OnionArch - 如何实现更新指定字段的通用Handler
博主最近失业在家,找工作之余,自己动手写了个洋葱架构(整洁架构)解决方案,以总结和整理以前的项目经验,起名叫OnionArch,其目的是为了更好的实现采用DDD(领域驱动分析)和命令查询职责分离(CQ ...
- Java注解(2):实现自己的ORM
搞过Java的码农都知道,在J2EE开发中一个(确切地说,应该是一类)很重要的框架,那就是ORM(Object Relational Mapping,对象关系映射).它把Java中的类和数据库中的表关 ...
- 【算法】基础DP
参考资料 背包九讲 一.线性DP 如果现在在状态 i 下,它上一步可能的状态是什么. 上一步不同的状态依赖于什么. 根据上面的分析,分析出状态和转移方程.注意:dp 不一定只有两维或者一维,一开始设计 ...
- CURL提交--POST/GET-带header信息
function https_request($url, $param, $data = '', $method = 'GET', $headers = '') { $opts = array( CU ...
- 齐博x2是什么?
齐博x2是什么? 齐博x2是齐博x1的延申版本. 对小程序全方位加强
- 3.pytest断言assert
pytest使用的python自带的断言assert关键字,和unittest封装的assert断言不一样 原理:用来测试某个断言条件,如果断言条件为True,则程序将继续正常执行:但如果断言条件为假 ...
- go:快速添加接口方法及其实现
问题描述 在大型项目中,通常存在多个模块,模块对外暴露的功能通常是通过接口封装,这样可以明确模块的功能,有效降低模块与模块之间的耦合度,同时模块与模块之间进行合理的组装.接口的实现,有时可能存在多个实 ...
- Kubernetes安装GitLab
个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying Kubernetes安装GitLab Step 1 ...
- 深度学习之深L层神经网络
声明 本文参考(8条消息) [中文][吴恩达课后编程作业]Course 1 - 神经网络和深度学习 - 第四周作业(1&2)_何宽的博客-CSDN博客 力求自己理解,刚刚走进深度学习希望可以一 ...
- bugku 秋名山老司机
看到这个的第一眼怀疑是脚本题,先看看源码 找不到提交点... 抓包 也没有 多刷新几次 弹出了提示信息 用post传入的参数value,其值应该就是计算式的答案 然后直接使用py脚本来快速上传答案值就 ...