Linux 设定文件和目录的权限
演示:文件的读写权限
1 | [root@localhost 验证]# tree -N |
创建新文件时,文件的权限受到两方面的影响,一个是umask值,另一个是重定向命令(>
)的open调用时指定的文件权限。
没有修改权限的文件,依旧可以删除:
1 | [root@localhost 验证]# tree -N |
创建新文件时,文件的权限受到两方面的影响,一个是umask值,另一个是重定向命令(>
)的open调用时指定的文件权限。
没有修改权限的文件,依旧可以删除:
有关选项-l和-d
例:ls -l
可以查当前目录下所有文件和子目录的权限
1 | [root@localhost Linux命令风格;文件系统]# ls -l |
ls -ld .
列出当前目录自身的权限:
1 | [root@localhost Linux命令风格;文件系统]# ls -ld |
字母形式
1 | chmod [ugoa][+-=][rwxst] 文件名表 |
u–user 文件主的权限
g–group 同组用户的权限
o–other 其他用户权限
a–all 所有上述三级权限
(t–Sticky, s–SUID)
例:
1 | chmod u+rw * # 所有的文件的文件主都加上读权限和写权限 |
数字形式(八进制数字)
例:
1 | chmod 644 xyz1 xyz2 |
八进制: | 6 | 4 | 4 |
---|---|---|---|
二进制: | 110 | 100 | 100 |
权限: | rw- | r– | r– |
注意: 只允许文件主和超级用户修改文件权限
这些新创建的文件或目录的权限就可以使用umask来指定。
打印当前的umask值:
1 | umask |
将umask值设置为八进制的022
1 | umask 022 |
例:
掩码值:022
二进制:000 010 010
取消新文件和新目录的组的w权限和其他用户的w权限
1 | [root@localhost 文件和目录的权限]# umask |
禁止组的所有权限和其他用户的所有权限(比特为1的地方的权限被屏蔽掉)
1 | umask 077 |
umask对当前shell进程有效,关闭当前shell后,umask属性将会丢失。
所以,如果需要的话,一般将umask命令放到shell自动执行批处理文件中
例如放到bash用户偏好文件中($HOME/.bash_profile
),
查看当前shell进程的umask值,查看当前目录的权限:
1 | [root@localhost 文件和目录的权限]# ls |
修改当前shell进程的umask值为077,已经存在的目录不会受影响:
1 | [root@localhost 文件和目录的权限]# umask 077 |
新创建的目录或文件的权限将受影响:
1 | [root@localhost 文件和目录的权限]# mkdir sonDir |
修改shell进程的umask值后,对整个shell进程创建的新目录或文件都有影响:
1 | [root@localhost 文件和目录的权限]# cd .. |
umask命令只对当前shell有效,重新打开一个shell,umask为默认值022:
1 | [root@localhost 文件和目录的权限]# ls -ld |
另一个shell的umask命令不会影响当前shell新创建的目录或文件的权限:
1 | [root@localhost 文件和目录的权限]# touch newShellnewFile.c |
修改进程自身的umask属性值
例:当umask为077时,用C程序
1 | fd=open(filename,O_CREAT|O_WRONLY,0666); |
open的权限为0666,经过umask屏蔽掉077后文件的实际权限为0600
1 | int umask(int mask); |
cd ../st8
要求当前目录,..
和st8
必须有x权限drwxrwxrwt 13 root root 20480 Mar 22 06:11 /tmp
每个文件都有文件主和组的属性(文件节点中)
每个进程也有进程主和组的属性(进程PCB中)
这四个属性都是整数,uid和gid的编号与名字对应关系见/etc下passwd和group文件
直接使用文件主的权限,不再查看组和其他用户的权限
只使用组权限,不使用关于其他用户的权限
使用文件关于其他用户的权限。
注意:超级用户root不受权限的限制
例:权限---r--rw-
,文件主不可读但同组用户可读,即使文件主是该组用户之一也不行
用于控制进程对系统中文件和目录的访问
/bin/sh
#!
必须是这个文件首先出现的两个字符),例如:1 | #!/bin/bash |
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。
CentOS系统有可能默认没有安装C语言帮助手册,man一个函数时会找不到帮助文件,用下面的命令安装:
1 | yum install man-pages.noarch |
1 | [root@localhost Linux命令风格;文件系统]# man malloc |
1 | [root@localhost Linux命令风格;文件系统]# yum install man-pages.noarch |
1 | MALLOC(3) Linux Programmer's Manual MALLOC(3) |
1 | PRINTF(3) Linux Programmer's Manual PRINTF(3) |
https://blog.csdn.net/yasi_xi/article/details/8658333
https://blog.csdn.net/caiyaodeng/article/details/45291905
从i节点获得文件的状态信息
stat和fstat将数据放入调用者提供的stat结构中
1 | #include <sys/types.h> |
st_dev:存储该文件的块设备的设备号,包括主设备号与次设备号
例如stat命令显示文件Device: 821h/2081d
十六进制0821,主设备号8(高字节),次设备号33(低字节), /dev/sdc1
1 | ls -l /dev | grep '^b.* 8, *33' |
文件的基本存取权限和SUID/SGID权限(11比特)以及文件的类型(若干比特)
文件类型判st_mode & S_IFMT
S_IFREG 普通磁盘文件
S_IFDIR 目录文件
S_IFCHR 字符设备文件
S_IFIFO 管道文件
S_IFLNK 符号连接文件
程序可以通过st_size获取文件大小。
一般情况:st_size ≤ st_blocks * 512
稀疏文件:st_size > st_blocks * 512
Linux中存储这三个时间的精度为纳秒
“a访问”:读,执行(有些系统为了效率做懒惰处理,不更新,但不早于m时间)
“m修改”:文件内容修改。写文件
“c改变”:i节点信息变化。写文件,修改权限/link数/文件主等(m变,c也变)
早期的UNIX象普通磁盘文件那样open()打开目录read()读取
现在的系统不再这样操作,而是直接使用封装好的库函数
1 | #include <dirent.h> |
opendir打开目录得到句柄(NULL表示失败)
readdir获取一个目录项
1 | #include <stdio.h> |
运行效果:
1 | [root@localhost Linux命令风格;文件系统]# ./dir . |
由此,可以编程构造诸如ls, rm, find等类似的工具,并理解系统命令是如何实现的。
例如:获取进程ID的getpid()与字符串拷贝函数strcpy()
CPU的INT指令(软中断)与CALL指令(子程序调用)
目的:执行效率更高或者调用界面更方便。例如:
库函数printf对系统调用write的封装
库函数malloc/free对系统调用sbrk的封装
系统调用和相关API函数以及库函数的名称、参数排列顺序、参数类型,返回值的类型,以及实现的功能,都属于类似POSIX标准规范的内容,便于不同Unix系统之间的移植。
一般返回一个整数值
标准库为errno保留存储空间,系统调用失败后填写错误代码,记录失败原因#include <errno.h>
之后,就可以直接使用变量errno.
errno.h头文件定义了许多有E前缀的宏,例如
1 | EACCESS,EIO,ENOMEM,EINTR |
相关系统调用的手册页中有出错说明
在man命令给出的手册页中有ERRORS一节介绍出错原因,如man recv
1 | char *strerror(int errno); |
errno是个整数,便于程序识别错误原因,不便于操作员理解失败原因。
库函数strerror将数字形式的错误代码转换成一个可阅读的字符串
printf类函数格式字符串中的%m会被替换成上次系统调用失败的错误代码对应的消息(message)
1 | #include <fcntl.h> |
创建openfile.c并编编译成可执行文件openfile:
1 | [root@localhost Linux命令风格;文件系统]# vim openfile.c |
输入一个存在的文件,运行效果如下:
1 | [root@localhost Linux命令风格;文件系统]# ./openfile useEnvC |
可以看到没有错误输出。
1 | 故意输入一个不存在的文件,运行效果如下: |
[root@localhost Linux命令风格;文件系统]# ./openfile useEnv.c
ERROR 2: No such file or directory
ERROR [No such file or directory]
[root@localhost Linux命令风格;文件系统]#
1 | ln -s users_on sym.link |
若符号链接包含绝对路径名,引用绝对路径名
若符号链接包含相对路径名,是相对于符号链接文件的位置(不是相对于调用进程的当前工作目录)
设当前目录(bash进程的当前目录)为d
1 | ln -s d1/dlb d1/dx |
在d1下新建文件dx
访问d1/dx实际访问d1/d1/d1b
https://blog.csdn.net/x534119219/article/details/79111936
1 | C:\Users\my>mklink /? |
在D:\网络共享
目录下,给G:\dev2\idea_workspace\MyJavaTools\runable
目录创建一个同名的符号链接:
1 | C:\Users\my>mklink /j D:\网络共享\runable G:\dev2\idea_workspace\MyJavaTools\runable |
文件名-i节点号
”对文件名-i节点号
”映射关系,叫做1个硬连接创建一个文件的硬链接:
1 | [root@localhost Linux命令风格;文件系统]# ls |
查看文件以及文件的硬链接的详细信息:
1 | [root@localhost Linux命令风格;文件系统]# ls -l |
可以发现useEnv.c和useEnvC的前几项都完全相同。而useEnv.c和useEnvC的link数都是2.
查看文件的i节点:
1 | [root@localhost Linux命令风格;文件系统]# ls -i |
可以发现文件useEnv.c和useEnvC的i节点都相同。
useEnv.c与useEnvC同时存在时,地位完全平等,硬链接创建完毕后,就无法知道哪个文件是先创建的,哪个文件是后创建的。
删除useEnv.c文件,
1 | [root@localhost Linux命令风格;文件系统]# rm useEnv.c |
可以发现则useEnvC仍存在但link数减1。
只有一个文件的link数减到0时,该文件的磁盘空间才会被清理掉。
硬连接,只限于同一文件系统中的普通文件
不允许对目录用ln命令建立硬连接
一般来说,目录的link数=直属子目录数+2
目录表的硬连接示意图:
可以对同一个文件起不同的文件名
一个文件位于另一个个文件系统中,不同的文件系统的i节点不能通用。
也就是硬链接不能跨越文件系统。
把整个逻辑设备以块(扇区) 为单位为划分,编号为0,1,2,…。
(每块512字节或其他更大$2^n$字节大小)
用于启动系统,只有根文件系统的引导块有效
也叫管理块,或者超级块
1 | [root@localhost Linux命令风格;文件系统]# df -h |
i节点区:i节点(index node,简记为i-node)
用于存放文件数据的区域,包括目录表
Linux目录结构是树形带交叉勾连的目录结构
主要目的:分开存放的主要目的是为了提高目录检索效率
两种方案的比较
示例:
1 | [root@localhost Linux命令风格;文件系统]# stat useEnv.c |