Linux系统对目录和文件有极其严格的保护,只有获得相关权限的用户才能进行指定的操作。进程是出于活动状态下的程序,用户通过操作系统运行程序所产生的进程代表这该用户的行为,如果该用户不具备访问某个目录和文件的权限,那么该用户的进程也不能被访问。
1文件的属性与权限
属性和权限是Linux系统中目录和文件的两个基本特性,他们决定文件的使用方法和安全性问题。
1.1 文件的属性
Linux系统中文件的安全机制是通过系统中的文件赋予所有者属性和访问权限属性来实现的
Linux系统下的每一个文件必须严格地属于一个用户和一个组,针对不同的用户和组又具有不同的访问权限。
在终端查看文件或目录的属性,可使用下面这个命令
ls -l
1.2 文件的权限
在上面这个图中我们可以看到文件的信息。每一行的第一组的第一个字符表示文件的类型,d为目录,-为普通文件,b为块输入输出设备文件(通常是磁盘驱动器),c为连续输入输出设备(通常是声卡,调制器等),l为连接文件,p为管道文件。
后面紧跟的三个字符为所有者权限,接着后面三个字符为群组权限,后三个为其他用户。其中r表示可读,w表示可写,x表示可执行,-为不允许。
第二组的数字表示该文件拥有的链接数,第三组和第四组分别表示所有者名称和群组名称。第5组表示文件的长度,第6组表示文件修改时间,最后一个表示文件的名称。
例如:第一行为 目录文件,所有者可读可写可执行,群众可读不可写能执行,其他用户读不可写能执行,拥有2个链接数,所有者,群众名为sanmu,文件大小为4096,修改时间为11月23日 22点52分,名称为公共的。
1.3管理文件的权限
修改文件权限的命令为chmod.格式为:
chmod [ugoa...] [[+/-/=] [rwx..] [文件名]]
第一组为所涉及到的用户,参数u为所有者,g为群众,o为其他用户,a为全部用户。第二组为对权限的操作 参数+为增加权限,-为取消权限,=为唯一设定权限。第三组为 r读 w写 x执行。最后为要设置的文件名。
chmod ug+w,o-w test1.c test1.h
该指令修改了文件test1.c test1.h的权限,所有者和群组获得了写的权限,其他用户取消了写的权限。
注意:如果修改文件的用户本身没有这个权限,则无法修改权限,系统将提示无权进行该操作。根用户可修改任意文件的权限。
除了这种修改方式,chmod命令还支持加权的方式进行设置,
chmod lmn [文件名]
l m n 分别代表了所有者,群众,其他用户的权限。读用4表示,写用2表示,执行用1表示,最后用户获得的权限为三者数值之和。rwx 为7,rx为5 ,wx为3
chmod 773 test2.c
表示文件test.c 所有者为可读可写可执行,群众为可读可写可执行,其他用户为可写可执行。
2文件管理
一般文件的操作供分为三种打开文件(open()),新建文件(creat()),关闭文件(close())。
打开文件可以使用系统调用函数open(),这个函数的作用是建立一个文件描述符,其他的函数可以通过这个文件描述符对指定的文件进行读和写。
open(文件路径,标志)
函数的返回值是文件描述符,如果打开成功的话会返回一个正整数,失败的话会返回-1.
标志分为主标志和副标志。主标志只能有一个,副标志可以同时有多个。
主标志
参数 | 说明 |
---|---|
O_RDONLY | 以只读的方式打开 |
O_WRONLY | 以只写的方式打开 |
O_RDWR | 以可读可写的方式打开 |
副标志
参数 | 说明 |
---|---|
O_APPEND | 读写文件从文件尾部开始移动,所写入的数据追加到文件尾部 |
O_TRUNC | 若文件存在并可以以写的方式打开时,此标志将文件长度给清零 |
O_CREAT | 若路径中的文件不存在,则会自动建立新文件 |
O_EXCL | 如果和O_CREAT同时存在,此指令会检测文件是否存在,不存在创建新文件,存在的话,返回错误信息-1 |
用open()加O_CREAT副标志创建新文件时,可同时设置文件的权限。
oped(文件路径,标志,权限标志);
权限标志可用前面提到的加权表示的方式,这里就不重复了。
新建文件的另一个函数为creat();
creat(文件路径,加权数);
创建成功会返回0,失败则返回-1;当文件不需要在使用时可以用close()函数来关闭close(文件描述符)。如果关闭成功,返回0,失败则返回-1;
3应用
1 #include <fcntl.h> //提供函数open()
2 #include <sys/types.h> //提供类型mode_t
3 #include <sys/stat.h> //提供open()函数符号
4 #include <unistd.h> //提供函数close()
5 #include <stdio.h>
6
7 #define qx 771
8 int main()
9 {
10 int f; //声明变量f ,用于存放文件标识符
11 const char *f_path="test"; //定义路径字符串
12 f=open(f_path,O_RDONLY); //以只读到方式打开test
13 if(f==-1) //打开失败
14 {
15 f=open(f_path,O_RDONLY | O_CREAT,qx); //创建test文件,权限771
16 if(f != -1) //创建成功
17 {
18 puts("创建一个新文件");
19 }
20 else //创建失败
21 {
22 puts("无法创建新文件,退出");
23 return 1;
24 }
25 }
26 else //打开成功
27 puts("文件打开成功");
28 close(f); //关闭文件 test1
29 return 0;
30
31 }
~
3文件状态和文件属性操作
获取文件状态和属性可使用fstat(),lstat()和stat()这三个函数来操作。fstat()函数用来返回一个已打开是文件的状态和属性信息,lstat()he stat()可对未打开文件进行操作。他俩的区别是,当一个文件是符号链接时,lstat返回的是该符号链接本身的信息,而stat则是返回该链接文件指向的文件的信息。
fstat(文件标识符,struct stat *buf);
lstat(路径,struct stat *buf);
stat(路径,struct stat *buf);
结构体struct stat 类型是stat.h函数库提供的一种用于保存文件类型的结构体。
成员名称 | 说明 |
---|---|
st_mode | 文件权限和文件类型信息 |
st_ino | 与该文件关联的inode |
st_dev | 文件保存在其上的设备 |
st_uid | 文件所有者的用户身份表示 |
st_gid | 文件群组的分组身份标识 |
st_atime | 上次被访问时间 |
st_ctime | 文件权限,所有者,群众或内容方面上次被修改时间 |
st_mtime | 文件内容方面被修改时间 |
st_nlink | 该文件上硬连接的个数 |
3目录操作
新建目录操作可使用函数mkdir()实现,
mkdir(路径,umask)
当目录创建成功时函数返回0,否则返回-1;
获取当前工作目录的操作可使用函数getcwd(),
getcwd(char *buf,size_t size);
其中 *buf 是存放当前目录缓冲区,size是缓冲区的大小,如果函数返回超过当前目录的字符串长度的话,他将返回NULL;
如果要改变程序的工作目录的话,可以使用函数chdir(),和shell里的cd命令一样。
chdir(路径)
删除目录和文件
unlink(路径)
该函数必须在该目录下没有子目录或文件的情况下才能执行。
if(mkdir("testdir",0774) != -1) //创建一个目录 所有者读 写 执行 。群组 读 写 执行。其他用户 读
puts(创建目录成功");
else
return 1;
if(creat("test1",0664) != -1) //创建一个文件 所有者读 写 。群组 读 写 。其他用户 读
puts(创建文件成功");
else
return 2;
if(unlink("test1") != -1) //删除 刚创建的文件
puts(删除文件成功");
else
return 3;
if(unlink("testdir") != -1) //删除 刚创建的目录
puts(删除目录成功");
else
return 4;
4错误处理
在进行文件操作的过程中可能出现各种原因而失败,错误信息将以代码的形式保存在系统变量errno中。这些错误信息被保存在errno.h内。
errno本身实质是一个int类型的数字,每个数字编号对应一种错误。当我们只看errno时只能得到一个错误编号数字(比如-37),不适应于人看。linux系统提供了一个函数perror(意思print error),perror函数内部会读取errno并且将这个不好认的数字直接给转成对应的错误信息字符串,然后print打印出来。