本文为《鸟哥的 Linux 私房菜》读书笔记
用户与用户组
Linux 中,任何一个文件都有 User (用户)、Group (所属群组)、Others (其他人) 三种身份的个别权限 ,这样设置有利于系统安全以及团队合作开发;User 表示文件拥有者,Group 表示文件所属群组 (一个群组内包含若干个用户),Others 表示并非 User 和 Group 中用户的其他用户
root 具有至高权力
每个账号可以加入的用户组个数基本没有限制
Linux 用户身份与用户组记录的文件
默认的情况下,所有的系统帐号与一般身份用户的相关信息 , 都是记录在 /etc/passwd
文件内
个人密码 则记录在 /etc/shadow
所有的群组名称 都记录在 /etc/group
Linux 文件权限
richard@richard-ubuntu:~$ ls -al
total 48
drwxr-xr-x 23 richard richard 4096 1月 28 20:41 .
drwxr-xr-x 3 root root 21 12月 7 18:45 ..
-rw------- 1 richard richard 2927 1月 31 15:54 .bash_history
-rw-r--r-- 1 richard richard 220 12月 7 18:45 .bash_logout
-rw-r--r-- 1 richard richard 3822 1月 20 17:41 .bashrc
drwx------ 16 richard richard 4096 1月 24 15:04 .cache
drwx------ 17 richard richard 313 1月 24 15:04 .config
drwx------ 3 richard richard 25 12月 7 13:22 .dbus
[ 文件权限类型 ] [ 链接] [ 拥有者] [ 用户组] [ 文件大小( Bytes) ] [ 修改日期 ] [ 文件名 ]
.. .
文件权限类型
第一个字符表示该文件的类型
d
表示目录 ;-
表示常规文件 ;l
表示链接文件
设备文件 (通常集中在 /dev
目录下):b
表示区块设备文件 ,可按块随机读写 (磁盘、flash…);c
表示字符设备文件 ,即串行端口设备 (键盘、鼠标…)
s
表示 socket (网络编程里作为运输层和应用层间软件接口的 socket)
p
表示数据输送文件 (FIFO)
接下来的字符中,三个为一组,且均为 rwx
的组合 (可读、可写、可执行),如果没有对应权限,则用 -
表示;这三组分别为 User、Group、Others 对应的权限
目录主要存储文件名列表 ,对于目录 d
来说
r
表示读取目录结构列表的权限 ,但详细的信息还是读不到 (要想使用 ls
命令必须还要给予 x
权限)
w
表示改动该目录结构列表的权限 ,包括:
新建 文件与目录、删除 已存在的文件与目录、 将已存在的文件与目录改名 、移动 该目录内的文件与目录位置
x
表示进入该目录的权限 (cd
)
因此,要开放目录给别人浏览时,应该至少给予 r
和 x
的权限
链接 :表示有多少文件名链接到此节点 (inode)
每个文件都会将它的权限与属性记录到文件系统的 inode 中,但目录树却是使用文件名来记录, 因此每个文件名就会链接到一个 inode,这个属性记录的就是有多少不同的文件名链接到相同的 inode 号码
时间参数:
修改时间 (默认) (modification time, m t i m e mtime m t i m e ):当该文件的“内容数据 ”变更时,就会更新这个时间
状态时间 (status time, c t i m e ctime c t i m e ):当该文件的“状态 ”(权限、属性…)变更时,就会更新这个时间
读取时间 (access time, a t i m e atime a t i m e ):当该文件的“内容被读取 ”时,就会更新这个时间
文件名之前多一个 .
表示该文件为隐藏文件 ,如果只输入 ls
的话不会显示,只有输入 ls -a
才会显示
文件默认权限
umask 就是指定 “目前用户在创建文件或目录时的默认权限 ”;目录与文件的默认权限是不一样的
文件默认权限为 -rw-rw-rw-
目录默认权限为 drwxrwxrwx
$ umask
0002
$ umask -S
u= rwx,g= rwx,o= rx
$ mkdir ttt
$ touch tt
$ ll | grep tt
-rw-rw-r-- 1 richard richard 0 2月 5 09:53 tt
drwxrwxr-x 2 richard richard 6 2月 5 09:52 ttt/
$ umask 022
文件隐藏属性
文件还可以设置一堆隐藏属性,详见 chattr
例如,要是碰到明明有 w
权限却还是不能修改的文件,不妨用 lsattr
看看隐藏属性,说不定设置了隐藏属性 i
文件特殊权限: SUID, SGID, SBIT
Set UID (SUID)
当 s
这个标志出现在文件拥有者的 x
权限上 时 (例如 -rwsr-xr-x
),此时就被称为 Set UID ,简称为 SUID 的特殊权限
SUID 权限仅对二进制程序有效 (不能用于 shell 脚本)
执行者对于该程序需要具有 x
的可执行权限
本权限仅在执行该程序的过程中有效 (run-time)
执行者将具有该程序拥有者 (owner) 的权限
例如,所有帐号的密码都记录在 /etc/shadow
中,这个文件的权限为:-rw-r----- 1 root shadow
,仅有 root
有权写入,那一般用户为什么能用 passwd
更改自己的密码?原因就在于 passwd
具有 SUID 特殊权限 :-rwsr-xr-x 1 root root
.
一般用户对 passwd
具有 x
权限
passwd
拥有者为 root
因此一般用户在执行 passwd
的过程中,会暂时获得 root
的权限,因此能修改 /etc/shadow
Set GID (SGID)
当 s
这个标志出现在用户组的 x
权限上 时 (例如 -rwxr-sr-x
),此时就被称为 Set GID ,简称为 SGID 的特殊权限。,SGID 可以针对文件或目录来设置
如果是对文件 来说, SGID 有如下的功能:
SUID 权限仅对二进制程序有效 (不能用于 shell 脚本)
执行者对于该程序需要具有 x
的可执行权限
执行者将在执行该程序的时 (run-time)具有该程序用户组的权限
如果是对目录 来说, SGID 有如下的功能:
用户若对于此目录具有 r
与 x
权限 时,该使用者能够进入此目录
用户在此目录下的有效用户组 (effective group)将会变成该目录的用户组
用途:若使用者在此目录下具有 w
的权限,则使用者所创建的新文件的用户组与此目录的用户组相同 ,这对项目开发来说是很重要的
Sticky Bit (SBIT)
SBIT 目前只针对目录 有效:
当用户对于此目录具有 w, x
权限 ,亦即具有写入的权限时
当用户在该目录下创建文件或目录时,仅有自己与 root
才有权力删除该文件
例如,/tmp
的权限就是 drwxrwxrwt
, 在这样的权限内容下,任何人都可以在 /tmp
内新增、修改文件,但仅有该文件/目录创建者与 root
能够删除自己的目录或文件
$ ll / | grep tmp
drwxrwxrwt 23 root root 4096 2月 5 10:20 tmp/
Linux 目录配置
目录树结构 (directory tree)
以根目录 /
为主,向下延伸
每一个目录不止能使用本地分区的文件系统,也可以使用网络上的 文件系统。例如, 可以利用 Network File System (NFS ) 服务器挂载某特定目录
文件系统与目录树的关系 (挂载)
Linux 使用的是目录树结构,但是我们的文件数据其实是放置在磁盘分区当中的;挂载 (mount) 可以结合目录树的架构与磁盘内的数据
挂载 就是利用一个目录当成进入点,将磁盘分区的数据放置在该目录下 ; 也就是说,进入该目录就可以读取该分区 ,那个进入点的目录我们称为 挂载点
由于整个 Linux 系统最重要的是根目录,因此根目录一定需要挂载到某个分区
可以通过反向追踪判断某个文件存储在哪个partition下 。以下图来说, 当我想要知道/home/vbird/test
这个文件在哪个partition时,由test --> vbird --> home --> /
,看哪个进入点先被查到那就是使用的进入点了。 所以test
使用的是/home
这个进入点而不是/
Linux 目录配置的依据–FHS
Filesystem Hierarchy Standard
每个 Linux 发行版的配置文件、执行文件、每个目录内放的东西都差不多,这也是因为它们都遵循了 FHS
FHS 将目录定义成为四种交互作用的形态
可分享 :能分享给网络上其他主机挂载用的目录
不变 :不随发行版变动的数据
可分享(shareable)
不可分享(unshareable)
不变(static)
/usr
/etc
/opt
/boot
可变动(variable)
/var/mail
/var/run
/var/spool/news
/var/lock
根目录的意义与内容
根目录是整个系统最重要的一个目录 ,因为不但所有的目录都是由根目录衍生出来 ,同时根目录也与启动/还原/系统修复等操作有关
因为根目录是这么的重要,所以 FHS 建议:根目录不要放在非常大的分区内 , 因为越大的分区你会放入越多的数据,如此一来根目录所在分区就可能会有较多发生错误的机会。应用程序所安装的软件最好不要与根目录放在同一个分区内 ,保持根目录越小越好。 如此不但性能较佳,根目录所在的文件系统也较不容易发生问题
早期 Linux 在设计的时候,若发生问题时,恢复模式通常仅挂载根目录,因此有五个重要的目录被要求一定要与根目录放置在一起: /etc
, /bin
, /dev
, /lib
, /sbin
目录
应放置的文件内容
(一) FHS 要求必须要存在的目录
/bin
放置在单人维护模式下还能被使用的命令 (cat
, chmod
, chown
, date
, mv
, mkdir
, cp
, bash
…)
/boot
放置开机会使用到的文件 ,包括 Linux 内核文件以及启动选项与启动所需配置文件等。 Linux kernel 常用的文件名为:vmlinuz
,如果使用的是 grub2 这个启动引导程序, 则还会存在 /boot/grub2/
这个目录
/dev
在 Linux 系统上,任何设备与接口设备都是以文件的形式存在于这个目录当中的。 读写这个目录下面的某个文件就等于读写某个设备
/etc
系统主要的配置文件 几乎都放置在这个目录内。一般来说,这个目录下的各文件属性可以让一般用户查看, 但只有root有权力修改 。FHS 还规范几个重要的目录最好要存在 /etc/
目录下:/etc/opt
(必要) :放置第三方辅助软件 /opt
的相关配置文件;/etc/X11/
(建议):放置与 X Window 有关的各种配置文件,尤其是 xorg.conf
这个 X Server 的配置文件; /etc/sgml/
(建议):与 SGML 格式有关的各项配置文件;/etc/xml/
(建议):与 XML 格式有关的各项配置文件
/lib
放置启动时会用到的函数库, 以及在 /bin
或 /sbin
下面的指令会调用的函数库 。 另外 FSH 还要求 /lib/modules/
目录必须要存在:这个目录主要放置可抽换式的内核相关模块 (驱动程序)
/media
放置可删除的设备。包括软盘、光盘、DVD等等设备都暂时挂载于此。常见的文件名有:/media/floppy
, /media/cdrom
等
/mnt
如果你想要暂时挂载某些额外的设备 ,一般建议你可以放置到这个目录中
/opt
放置第三方辅助软件 的目录
/run
/run
可使用内存来模拟 ,主要放置系统启动后产生的各项信息;某些程序或者是服务启动后,会将它们的 PID 放置在这个目录下
/sbin
放置启动过程中所需要的 (包括启动、修复、还原系统) 指令。 至于某些服务器软件程序,一般则放置到 /usr/sbin/
中。至于本机自行安装的软件所产生的系统可执行文件(system binary), 则放置到 /usr/local/sbin/
中。常见的指令包括:fdisk
, fsck
, ifconfig
, mkfs
等
/srv
是一些网络服务启动之后,这些服务所需要取用的数据目录。 例如,WWW 服务器需要的网页数据就可以放置在 /srv/www/
里
/tmp
这是让一般用户或者是正在执行的程序暂时放置文件的地方 。 这个目录是任何人都能够存取的,所以你需要定期的清理 一下。当然,重要数据不可放置在此目录
/usr
软件存放处 (Unix Software Resource),后面会详细说明
/var
主要放置变动性的数据 (缓存、日志、某些软件运行时产生的文件…),后面会详细说明
(二) FHS 建议可以存在的目录
/home
用户家目录
/lib<qual>
用来存放与 /lib
不同的格式的二进制函数库,例如支持 64 位的 /lib64
函数库等
/root
系统管理员(root)的家目录 。之所以放在这里,是因为如果进入单人维护模式而仅挂载根目录时, 该目录就能够拥有 /root
的家目录,所以我们会希望 root 的家目录与根目录放置在同一个分区中
(三) FHS 未规定但非常重要的目录
/proc
这个目录本身是一个“虚拟文件系统 ”,它放置的数据都在内存中 , 例如系统内核、进程信息、外接设备的状态及网络状态等。比较重要的文件例如:/proc/cpuinfo
, /proc/dma
,/proc/interrupts
, /proc/ioports
, /proc/net/*
等
/sys
也是一个虚拟文件系统 ,主要记录内核与系统硬件信息相关的信息 。 包括目前已载入的内核模块与内核检测到的硬件设备信息等
目录
应放置文件内容
(一) FHS 要求必须要存在的目录
/usr/bin/
所有一般用户能够使用的命令 都放在这里,目前 Ubuntu 已经将全部的用户命令放置于此,而使用链接文件的方式将 /bin
链接至此 。另外,FHS 要求在此目录下不应该有子目录
/usr/lib/
与 /lib
功能相同, /lib
就是链接到此目录中的
/usr/local/
系统管理员在本机安装自己下载的软件时建议安装到此目录 , 这样会比较便于管理
/usr/sbin/
与 /sbin
功能相同, /sbin
就是链接到此目录中的
/usr/share/
主要放置只读的数据文件 ,当然也包括共享文件。在这个目录下放置的数据几乎是不分硬件架构均可读取的数据, 因为几乎都是文本文件。在此目录下常见的还有这些次目录:/usr/share/man
:线上说明文档 /usr/share/doc
:软件杂项的文件说明 /usr/share/zoneinfo
:与时区有关的时区文件
(二) FHS 建议可以存在的目录
/usr/games/
放置游戏数据
/usr/include/
放置c/c++等程序语言的头文件与包含文件
/usr/libexec
/
放置某些不被一般用户常用的可执行文件或脚本等。例如大部分的 X 窗口下面的操作指令
/usr/lib<qual>/
与 /lib<qual>
功能相同, /lib<qual>
就是链接到此目录中的
/usr/src/
一般源代码 建议放置到这里。至于内核源代码则建议放置到 /usr/src/linux/
目录下
目录
应放置文件内容
(一) FHS 要求必须要存在的目录
/var/cache/
应用程序本身运行过程中会产生的一些缓存
/var/lib/
程序本身执行的过程中,需要使用到的数据文件放置的目录。在此目录下各自的软件应该要有各自的目录
/var/lock/
某些设备或者是文件资源一次只能被一个应用程序所使用,因此就得要将该设备上锁 (lock),以确保该设备只会给单一软件所使用;目前链接至 /run/lock
/var/log/
放置日志文件
/var/mail/
放置个人电子邮件的目录,不过这个目录也被放置到 /var/spool/mail/
目录中, 通常这两个目录是互为链接文件
/var/run/
这个目录链接到 /run
/var/spool/
这个目录通常放置一些队列数据 ,所谓的“队列”就是排队等待其他程序使用的数据。 这些数据被使用后通常都会被删除。举例来说,系统收到新信会放置到/var/spool/mail/
中, 但使用者收下该信件后该封信原则上就会被删除。信件如果暂时寄不出去会被放到/var/spool/mqueue/
中, 等到被送出后就被删除。如果是工作调度数据(crontab),就会被放置到/var/spool/cron/
目录中
各硬件设备在 Linux 中的文件名
在 Linux 系统中,每个设备都被当成一个文件来对待
几乎所有的硬件设备文件都在 /dev
目录内
设备
设备在 Linux 内的文件名
SCSI / SATA / USB 硬盘驱动器
/dev/sd[a-p]
打印机
/dev/lp[0-2]
(25针打印机); /dev/usb/lp[0-15]
(USB 接口)
鼠标
/dev/input/mouse[0-15]
(通用); /dev/psaux
(PS/2界面);/dev/mouse
(当前鼠标)
CDROM / DVDROM
/dev/scd[0-1]
(通用); /dev/sr[0-1]
(通用,CentOS 较常见); /dev/cdrom
(当前 CDROM)
SATA / USB / SAS 等磁盘接口都是使用 SCSI 模块 (Small Computer System Interface) 来驱动的, 因此这些接口的磁盘设备文件名都是 /dev/sd[a-p]
的格式
它们的设备文件名要根据 Linux 内核检测到磁盘的顺序来命名
例如:如果 PC 上有两个 SATA 磁盘以及一个 USB 磁盘,而主板上面有六个 SATA 插槽。这两个 SATA 磁盘分别安插在主板上的 SATA1, SATA5 插槽上;则
SATA1 插槽上的文件名:/dev/sda
SATA5 插槽上的文件名:/dev/sdb
USB 磁盘(开机完成后才被系统识别 ):/dev/sdc
关于可执行文件路径的变量: $PATH
我们知道查看文件属性的命令ls
完整文件名为:/bin/ls
, 那你会不会觉得很奇怪:为什么我在任何目录下输入 ls
就一定可以显示出一些信息而不会说找不到该 /bin/ls
命令呢? 这是因为环境变量 PATH
的帮助 所致
当我们在执行一个命令的时候,以 ls
为例,系统会依照 PATH
的设置依次去每个 PATH
定义的目录下搜寻文件名为 ls
的可执行文件 , 如果在 PATH
定义的目录中含有多个文件名为 ls
的可执行文件,那么先搜寻到的同名指令将先被执行
注意,如果 PATH
中没有当前工作目录,那就算可执行文件 a
在当前目录下,也不能直接输入 a
执行,而是要输入 ./a
不同用户默认的 PATH
不同 ,因此默认能随意执行的命令也不同
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
在 PATH
中加入新路径
$ PATH= "${PATH} :/root"