文件的基本操作(下)
文件属性
file
命令
语法
>$ file file0 [file1 file2 ...]
file
命令用于确认文件的类型。
在Linux
下,通常并不会严格按照文件扩展名来确定文件的类型,尤其是可执行程序往往是没有扩展名的。
file
命令可以查看文件的具体类型,如果是可执行程序,还会显示其位数、链接信息等数据,如下所示:
>$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d0bc0fb9b3f60f72bbad3c5a1d24c9e2a1fde775, stripped
stat
命令
语法
>$ stat file0 [file1 file2]
stat
命令用来查看文件的详细属性,类似于ls -l
,但它们又有所不同,我们通过一个例子来详解各个指标。
>$ stat /bin/ls
File: '/bin/ls'
Size: 126584 Blocks: 248 IO Block: 4096 regular file
Device: 805h/2053d Inode: 980781 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-06-12 21:03:56.231999815 +0800
Modify: 2017-03-03 02:07:22.000000000 +0800
Change: 2018-02-06 15:52:08.189466243 +0800
Birth: -
File
:文件名。
Size
:文件的大小,单位是字节。
Blocks
:文件占用了多少个数据块。(注意磁盘是块设备,数据是按块为基本单位存储的,而不是按照字节为基本单位。)
IO Block
:每个块能够存储多少字节的数据。
regular file
:这个字段是文件的类型。regular file
表示这是一个普通文件。
Device
:设备号。
Inode
:文件的Inode
号。Inode
是文件系统在磁盘上用来保存文件属性数据的,里面包含了除了文件名以外的所有文件属性。而文件名是保存在目录文件中的,目录也是文件,它是用来保存文件的特殊文件。
Links
:文件的硬链接数量。
Access
:文件权限。
Uid
:文件属主。
Gid
:文件属组。
Access Time
:又称atime
,表示文件的访问时间。当文件的内容被访问时更新此时间戳。
Modify Time
:又称mtime
,表示文件的修改时间。当文件的内容被修改时更新此时间戳。
Change Time
:又称ctime
,表示文件状态修改时间。当文件的状态(或属性)被修改时更新此时间戳,例如修改权限、创建或删除硬链接等等。
文件权限
chmod
命令
语法
>$ chmod [-R] mask name
chmod
命令是用来修改文件的权限
的。
在 Linux 系统中,任何一个文件都可以被分配三个权限,即可读
、可写
、可执行
。
而每个用户对一个文件而言都至少拥有下面三个身份中的一个,即文件的拥有者
、与文件拥有者在相同的用户组
、其他用户
。
那么这三个权限与三个身份之间有着什么样的联系呢,我们且先看一下某个文件的属性。
>$ ls -l /bin/ls
-rwxr-xr-x 1 root root 126584 3月 3 2017 /bin/ls
文件/bin/ls
的属性中,第一个字段-rwxr-xr-x
就表示文件的类型和权限,我们在后面进行详细介绍。接下来看第三和第四两个字段,均为root
。第一个root
表示文件归属于哪个用户,下文称其为文件的“属主”。第二个root
表示文件归属于哪个用户组,下文称其为文件的“属组”。其它的字段与权限无关,我们这里就不展开介绍了。
接下来我们先解释第一个字段的含义,把-rwxr-xr-x
分为四个部分来解读,如下表所示:
段 | 含义 |
---|---|
- | 文件类型 |
rwx | 属主的权限 |
r-x | 属组的权限 |
r-x | 其他用户的权限 |
表1 权限段
图1 文件权限
文件类型中的-
表示这是一个普通文件,常见的文件类型见下表:
标识符 | 类型 |
---|---|
d | 文件夹 |
- | 普通文件 |
l | 符号链接 |
p | 管道文件 |
b | 块设备文件 |
c | 字符设备文件 |
s | 套接字文件 |
表2 文件类型
文件权限部分共出现了4种字符,分别表示不同的权限,如下表所示:
标识符 | 八进制权重 | 权限 |
---|---|---|
r | 4 | 可读 |
w | 2 | 可写 |
x | 1 | 对文件表示可执行,对文件夹表示可进入 |
- | 0 | 无此权限 |
表3 权限值
由此我们可以解读出-rwxr-xr-x
表示:
这是一个普通文件;
文件的所有者对其拥有可读、可写、可执行的权限;
与文件所有者在相同用户组的用户对其拥有可读、可执行的权限;
其它用户拥有可读、可执行的权限。
文件权限的八进制表示法
权限中的 owner、group、other 的每一部分的权限分别可以计算出一个八进制值,三个八进制值合并在一块就可以表示一个文件的完整权限。
如表3所示,不同的权限对应着一个权重值,将每一部分权限的权重值相加就可以得到这一部分的权重。
还用上面的/bin/ls
文件的权限为例,它的八进制权限计算过程如下:
(r w x) (r - x) (r - x)
(4+2+1) (4+0+1) (4+0+1) = 7 5 5
因此-rwxr-xr-x
对应的八进制权限就是755
。
chmod
的用法
有了前面的知识,我们就可以看下chmod
命令的用法的。它在修改文件权限的时候既可使用八进制的形式也可使用标识符的形式来指示权限。
使用八进制方式修改文件的权限
我们通过下面的例子使用八进制的方式将/bin/ls
文件的权限修改为“属主可读、属组可读写、其他用户可执行”:
>$ $ sudo chmod 461 /bin/ls
>$ ls -l /bin/ls
-r--rw---x 1 root root 126584 3月 3 2017 /bin/ls
461权限对应的标识符是什么呢,大家可以根据前面学到的知识计算一下。
使用标识符的形式修改文件的权限
使用标识符的形式修改文件的权限,需要分别指定为哪个组别的用户修改权限,组别使用下表的字符来表示:
标识符 | 组别 |
---|---|
a | 所有用户 |
u | 属主 |
g | 属组 |
o | 其他用户 |
表4 组别标识符
使用表4中的组别标识符和表3的权限标识符组合,就可以修改对应组别的权限了。
通过下面的例子,我们将/bin/ls
文件的权限修改为“属主拥有可读、可写、可执行的权限;属组和其它用户均拥有可读和和执行的权限”。
>$ ls -l /bin/ls
-r--rw---x 1 root root 126584 3月 3 2017 /bin/ls
>$ sudo chmod u+wx /bin/ls
>$ ls -l /bin/ls
-rwxrw---x 1 root root 126584 3月 3 2017 /bin/ls
>$ sudo chmod g-w /bin/ls
>$ ls -l /bin/ls
-rwxr----x 1 root root 126584 3月 3 2017 /bin/ls
>$ sudo chmod g+x /bin/ls
>$ ls -l /bin/ls
-rwxr-x--x 1 root root 126584 3月 3 2017 /bin/ls
>$ sudo chmod o+r /bin/ls
>$ ls -l /bin/ls
-rwxr-xr-x 1 root root 126584 3月 3 2017 /bin/ls
上例中每一次修改我们都可以看到对应的权限发生了变化。
使用标识符来修改权限的一个常见的场景是在创建脚本的时候,出于安全方面的考量,一般情况使用touch
命令创建一个脚本文件后,该文件并不具备可执行的权限,我们需要手动为所有的用户都添加上可执行的权限,那么可以按照如下方式方便的授权:
>$ touch test.sh
>$ ls -l test.sh
-rw-rw-r-- 1 user user 0 6月 27 20:42 test.sh
>$ chmod a+x test.sh
>$ ls -l test.sh
-rwxrwxr-x 1 user user 0 6月 27 20:42 test.sh
从这个例子中可以清楚的看到,使用a+x
很方便的为所有的用户添加了可执行权限。
如果要递归为目录中的子文件修改权限,只需添加-R
参数即可,如下所示:
>$ chmod 777 -R /tmp/17bang
>$ chmod a+x -R /tmp/17bang
chown
命令
此命令用于修改文件或目录的属主,也可同时修改属组。
>$ chown user[:group] [-R] dir/file
通过上面chmod
命令我们知道了,文件的所有者和用户所在的用户组会决定一个用户对某个文件具有什么样的权限,那么chown
命令就是用来修改一个文件的属主和属组的。
使用示例:
>$ ls -l 17bang.txt
-rw-rw-r-- 1 user user 0 7月 5 18:51 17bang.txt
>$ sudo chown root 17bang.txt
>$ ls -l 17bang.txt
-rw-rw-r-- 1 root user 0 7月 5 18:51 17bang.txt
>$ sudo chown root:root 17bang.txt
>$ ls -l 17bang.txt
-rw-rw-r-- 1 root root 0 7月 5 18:51 17bang.txt
注意:chown
命令只有超级用户才能使用。
试想一下为什么会有这样的限定呢?
举个栗子来说,如果任何用户都可以使用chown
命令来修改文件的所有者,那么就可以轻易绕过磁盘配额的控制了。
假设管理员为用户A分配了一定的磁盘空间,当用户A的磁盘空间不足时,ta就可以通过chown
命令将某些文件的所有者修改为另一个用户B,这样这笔账就寄在用户B的头上了。当用户A需要使用此文件时,再将所有者改回来就行了。而用户B却完全不知道自己在用户A的家目录中还有所属的文件,白白的为用户A背了锅。
chgrp
命令
此命令专门用来修改文件和目录的属组,用法与chown
类似,这里就不再展开介绍了。
查找文件
which
、locate
和find
命令是三个常见的查找文件的命令,下面我们分别进行介绍。
which
命令
which
是 shell 的内建命令,通常用于查找某个命令的路径,因为它只从$PATH
环境变量所指定的路径中寻找文件。
>$ which ls
/bin/ls
locate
命令
locate
命令从/var/lib/mlocate/mlocate.db
数据库文件中查询文件的所在路径,因此检索速度非常快。
系统会在特定的时间自动调用updatedb
命令来更新这个数据库文件,因此locate
命令并不能查询到系统中最新添加的文件,而是要等待一定的时间后才能查询得到。
>$ locate .vimrc
/home/user/.vimrc
-c
参数可以统计数量。
-i
参数可以忽略大小写。
find
命令
find
命令是所有查找命令中最常用也最强大的,它不仅可以通过文件名来查询,也可以通过文件类型和属性来查找文件。
>$ find [path] [expression]
我们这里只举个用文件名查找文件的栗子。
>$ find /etc -name "*.conf"
/etc/depmod.d/ubuntu.conf
/etc/rsyslog.conf
/etc/sensors3.conf
/etc/ca-certificates.conf
......
如果不加路径,则默认为查找当前目录下的文件。
$ find -name "*.txt"
./.mozilla/firefox/s7tyv1vj.default-1530780643269/SiteSecurityServiceState.txt
./.mozilla/firefox/s7tyv1vj.default-1530780643269/pkcs11.txt
find
命令还有许多其它高级的用法,大家可以试着自己找找资料,并动手实验一下。
上面的内容不过瘾?更深入的知识可以参考LZ的博客:(三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录