7. 理解 Linux 文件權限
Linux 沿用了 Unix 文件權限的辦法,即允許用戶和組根據每個文件和目錄的安全性設置來訪問文件。
7.1 Linux 的安全性
Linux 安全系統的核心是用戶賬戶。每個能進入 Linux 系統的用戶都會被分配唯一的用戶賬戶。用戶對系統中各種對象的訪問權限取決於他們登錄系統時用
的賬戶。
用戶權限是通過創建用戶時分配的用戶 ID(User ID,通常縮寫爲UID)來跟蹤的。UID 是數值,每個用戶都有唯一的 UID,但在登錄系統時用的不是 UID,
而是登錄名。登錄名是用戶用來登錄系統的最長八字符的字符串(字符可以是數字或字母),同時會關聯一個對應的密碼。
Linux 系統使用特定的文件和工具來跟蹤和管理系統上的用戶賬戶。
7.1.1 /etc/passwd 文件
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 系統使用一個專門的文件來將用戶的登錄名匹配到對應的 UID 值。這個文件就是 /etc/passwd 文件,它包含了一些與用戶有關的信息。
[devalone@devalone ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
devalone:x:1000:1000:MichaelY.:/home/devalone:/bin/bash
...
root 用戶賬戶是 Linux 系統的管理員,固定分配給它的 UID 是 0。
Linux 系統會爲各種各樣的功能創建不同的用戶賬戶,而這些賬戶並不是真的用戶。這些賬戶叫作系統賬戶,是系統上運行的各種服務進程訪問資源用的
特殊賬戶。所有運行在後臺的服務都需要用一個系統用戶賬戶登錄到 Linux 系統上。
Linux 爲系統賬戶預留了 500 以下的 UID 值。有些服務甚至要用特定的 UID 才能正常工作。爲普通用戶創建賬戶時,大多數 Linux 系統會從 500 開始。
CentOS 7 從 1000 開始用於普通賬戶。
/etc/passwd 文件的字段包含了如下信息(每一行爲一個賬戶信息,以 : 分隔爲 7 個段,分別代表不同的信息):
□ 登錄用戶名
□ 用戶密碼
□ 用戶賬戶的 UID(數字形式)
□ 用戶賬戶的組 ID(GID)(數字形式)
□ 用戶賬戶的文本描述(稱爲備註字段)
□ 用戶 HOME 目錄的位置
□ 用戶的默認 shell
/etc/passwd 文件中的密碼字段都被設置成了x,這並不是說所有的用戶賬戶都用相同的密碼。現在,絕大多數 Linux 系統都將用戶密碼保存在另一個單獨
的文件中(叫作shadow文件,位於 /etc/shadow)。只有特定的程序(比如登錄程序)才能訪問這個文件
7.1.2 /etc/shadow 文件
-----------------------------------------------------------------------------------------------------------------------------------------
/etc/shadow 文件對 Linux 系統密碼管理提供了更多的控制。只有 root 用戶才能訪問 /etc/shadow 文件,這讓它比起 /etc/passwd 安全許多。
devalone:$6$9rZXEANeschIueWG$KReB.a2J518vAj3YUn9pprEQZABk.sFmQw7oG8UrTwmhzzSJy6vmMckohqSM1P4RSLxs23tHdg8nXHb8OcQoH0::0:99999:7:::
在/etc/shadow文件的每條記錄中都有 9 個字段:
□ 與/etc/passwd 文件中的登錄名字段對應的登錄名
□ 加密後的密碼
□ 自上次修改密碼後過去的天數密碼(自1970年1月1日開始計算)
□ 多少天后才能更改密碼
□ 多少天后必須更改密碼
□ 密碼過期前提前多少天提醒用戶更改密碼
□ 密碼過期後多少天禁用用戶賬戶
□ 用戶賬戶被禁用的日期(用自1970年1月1日到當天的天數表示)
□ 預留字段給將來使用
使用 shadow 密碼系統後,Linux 系統可以更好地控制用戶密碼。它可以控制用戶多久更改一次密碼,以及什麼時候禁用該用戶賬戶,如果密碼未更新的話。
7.1.3 添加新用戶
-----------------------------------------------------------------------------------------------------------------------------------------
用來向 Linux 系統添加新用戶的主要工具是 useradd。這個命令可以一次性創建新用戶賬戶及設置用戶 HOME 目錄結構。useradd 命令使用系統的默認值
以及命令行參數來設置用戶賬戶。系統默認值被設置在 /etc/default/useradd 文件中。可以使用加入了-D 選項的 useradd 命令查看所用 Linux 系統中的
這些默認值:
[devalone@devalone ~]$ cat /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
[devalone@devalone ~]$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
上述默認值說明:
□ 新用戶會被添加到 GID 爲 100 的公共組;
□ 新用戶的 HOME 目錄將會位於 /home/loginname;
□ 新用戶賬戶密碼在過期後不會被禁用;
□ 新用戶賬戶未被設置過期日期;
□ 新用戶賬戶將 bash shell 作爲默認 shell;
□ 系統會將 /etc/skel 目錄下的內容複製到用戶的 HOME 目錄下;
□ 系統爲該用戶賬戶在 mail 目錄下創建一個用於接收郵件的文件。
可以用默認系統參數創建一個新用戶賬戶,然後檢查一下新用戶的 HOME 目錄:
[root@devalone ~]# useradd -m usertest
[root@devalone ~]# ll /home/usertest
默認情況下,useradd 命令不會創建 HOME 目錄,但是 -m 命令行選項會使其創建 HOME 目錄。
useradd 命令行參數
+-------------------+-------------------------------------------------------------------------------------------------
| 參 數 | 描 述
+-------------------+-------------------------------------------------------------------------------------------------
| -c comment | 給新用戶添加備註
+-------------------+-------------------------------------------------------------------------------------------------
| -d home_dir | 爲主目錄指定一個名字(如果不想用登錄名作爲主目錄名的話)
+-------------------+-------------------------------------------------------------------------------------------------
| -e expire_date | 用YYYY-MM-DD格式指定一個賬戶過期的日期
+-------------------+-------------------------------------------------------------------------------------------------
| -f inactive_days | 指定這個賬戶密碼過期後多少天這個賬戶被禁用;0 表示密碼一過期就立即禁用,1 表示禁用這個功能
+-------------------+-------------------------------------------------------------------------------------------------
| -g initial_group | 指定用戶登錄組的GID或組名
+-------------------+-------------------------------------------------------------------------------------------------
| -G group ... | 指定用戶除登錄組之外所屬的一個或多個附加組
+-------------------+-------------------------------------------------------------------------------------------------
| -k | 必須和-m一起使用,將/etc/skel目錄的內容複製到用戶的HOME目錄
+-------------------+-------------------------------------------------------------------------------------------------
| -m | 創建用戶的HOME目錄
+-------------------+-------------------------------------------------------------------------------------------------
| -M | 不創建用戶的HOME目錄(當默認設置裏要求創建時才使用這個選項)
+-------------------+-------------------------------------------------------------------------------------------------
| -n | 創建一個與用戶登錄名同名的新組
+-------------------+-------------------------------------------------------------------------------------------------
| -r | 創建系統賬戶
+-------------------+-------------------------------------------------------------------------------------------------
| -p passwd | 爲用戶賬戶指定默認密碼
+-------------------+-------------------------------------------------------------------------------------------------
| -s shell | 指定默認的登錄shell
+-------------------+-------------------------------------------------------------------------------------------------
| -u uid | 爲賬戶指定唯一的UID
+-------------------+-------------------------------------------------------------------------------------------------
可以在 -D 選項後跟上一個指定的值來修改系統默認的新用戶設置:
+-------------------+-------------------------------------------------------------------------------------------------
| 參 數 | 描 述
+-------------------+-------------------------------------------------------------------------------------------------
| -b default_home | 更改默認的創建用戶HOME目錄的位置
+-------------------+-------------------------------------------------------------------------------------------------
| -e expiration_date| 更改默認的新賬戶的過期日期
+-------------------+-------------------------------------------------------------------------------------------------
| -f inactive | 更改默認的新用戶從密碼過期到賬戶被禁用的天數
+-------------------+-------------------------------------------------------------------------------------------------
| -g group | 更改默認的組名稱或GID
+-------------------+-------------------------------------------------------------------------------------------------
| -s shell | 更改默認的登錄shell
+-------------------+-------------------------------------------------------------------------------------------------
7.1.4 刪除用戶
-----------------------------------------------------------------------------------------------------------------------------------------
默認情況下,userdel 命令會只刪除 /etc/passwd 文件中的用戶信息,而不會刪除系統中屬於該賬戶的任何文件。
如果加上 -r 參數,userdel 會刪除用戶的 HOME 目錄以及郵件目錄。然而,系統上仍可能存有已刪除用戶的其他文件。這在有些環境中會造成問題。
[root@devalone ~]# userdel -r usertest
[root@devalone ~]# ll /home
總用量 20
drwx------. 55 devalone devalone 4096 7月 3 14:29 devalone
drwx------. 2 root root 16384 3月 9 2017 lost+found
7.1.5 修改用戶
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 提供了一些不同的工具來修改已有用戶賬戶的信息,如下表所示:
用戶賬戶修改工具:
+-----------+--------------------------------------------------------------------------------
| 命 令 | 描 述
+-----------+--------------------------------------------------------------------------------
| usermod | 修改用戶賬戶的字段,還可以指定主要組以及附加組的所屬關係
+-----------+--------------------------------------------------------------------------------
| passwd | 修改已有用戶的密碼
+-----------+--------------------------------------------------------------------------------
| chpasswd | 從文件中讀取登錄名密碼對,並更新密碼
+-----------+--------------------------------------------------------------------------------
| chage | 修改密碼的過期日期
+-----------+--------------------------------------------------------------------------------
| chfn | 修改用戶賬戶的備註信息
+-----------+--------------------------------------------------------------------------------
| chsh | 修改用戶賬戶的默認登錄shell
+-----------+--------------------------------------------------------------------------------
■ usermod
-------------------------------------------------------------------------------------------------------------------------------------
usermod 命令是用戶賬戶修改工具中最強大的一個。它能用來修改 /etc/passwd文件中的大部分字段,只需用與想修改的字段對應的命令行參數就可以了。
參數大部分跟 useradd 命令的參數一樣(比如,-c 修改備註字段,-e 修改過期日期,-g 修改默認的登錄組)。除此之外,還有另外一些可能派上用場
的選項:
-l 修改用戶賬戶的登錄名。
-L 鎖定賬戶,使用戶無法登錄。
-p 修改賬戶的密碼。
-U 解除鎖定,使用戶能夠登錄。
-L 選項尤其實用。它可以將賬戶鎖定,使用戶無法登錄,同時無需刪除賬戶和用戶的數據。要讓賬戶恢復正常,只要用-U選項就行了。
■ passwd 和 chpasswd
-------------------------------------------------------------------------------------------------------------------------------------
改變用戶密碼的一個簡便方法就是用 passwd 命令:
[root@devalone ~]# passwd user1
更改用戶 user1 的密碼 。
新的 密碼:
如果只用 passwd 命令,它會改自己的密碼。系統上的任何用戶都能改自己的密碼,但只有 root 用戶纔有權限改別人的密碼。
-e 選項能強制用戶下次登錄時修改密碼。可以先給用戶設置一個簡單的密碼,之後再強制在下次登錄時改成他們能記住的更復雜的密碼。
如果需要爲系統中的大量用戶修改密碼,chpasswd 命令可以事半功倍。chpasswd 命令能從標準輸入自動讀取登錄名和密碼對(由冒號分割)列表,
給密碼加密,然後爲用戶賬戶設置。也可以用重定向命令來將含有 userid:passwd 對的文件重定向給該命令:
[root@devalone ~]# chpasswd < users.txt
■ chsh、chfn 和 chage
-------------------------------------------------------------------------------------------------------------------------------------
chsh、chfn 和 chage 工具專門用來修改特定的賬戶信息。
chsh 命令用來快速修改默認的用戶登錄 shell。使用時必須用 shell 的全路徑名作爲參數,不能只用 shell 名。
# chsh -s /bin/csh user1
Changing shell for user1.
Shell changed.
chfn 命令提供了在 /etc/passwd 文件的備註字段中存儲信息的標準方法。chfn 命令會將用於 Unix 的 finger命令的信息存進備註字段,而不是簡單地
存入一些隨機文本(比如名字或暱稱之類的),或是將備註字段留空。finger 命令可以非常方便地查看 Linux 系統上的用戶信息:
[root@devalone ~]# finger devalone
Login: devalone Name: MichaelY.
Directory: /home/devalone Shell: /bin/bash
On since 三 7月 4 09:17 (CST) on pts/0 from 192.168.1.101
No mail.
No Plan.
如果在使用 chfn 命令時沒有參數,它會向詢問要將哪些適合的內容加進備註字段:
[root@devalone ~]# chfn user1
正在更改 user1 的 finger 信息。
名稱 []: user1 test
辦公 []: tech
辦公電話 []: 12334456
住宅電話 []: 22233345
Finger 信息已更改。
chage 命令用來幫助管理用戶賬戶的有效期。需要對每個值設置多個參數:
chage命令參數:
+-------+----------------------------------------------------------
| 參 數 | 描 述
+-------+----------------------------------------------------------
| -d | 設置上次修改密碼到現在的天數
+-------+----------------------------------------------------------
| -E | 設置密碼過期的日期
+-------+----------------------------------------------------------
| -I | 設置密碼過期到鎖定賬戶的天數
+-------+----------------------------------------------------------
| -m | 設置修改密碼之間最少要多少天
+-------+----------------------------------------------------------
| -W | 設置密碼過期前多久開始出現提醒信息
+-------+----------------------------------------------------------
chage 命令的日期值可以用下面兩種方式中的任意一種:
YYYY-MM-DD格式的日期
代表從1970年1月1日起到該日期天數的數值
7.2 使用 Linux 組
-----------------------------------------------------------------------------------------------------------------------------------------
組權限允許多個用戶對系統中的對象(比如文件、目錄或設備等)共享一組共用的權限。Linux 發行版在處理默認組的成員關係時略有差異。有些 Linux
發行版會創建一個組,把所有用戶都當作這個組的成員。遇到這種情況要特別小心,因爲文件很有可能對其他用戶也是可讀的。有些發行版會爲每個用戶創建
單獨的一個組,這樣可以更安全一些。
每個組都有唯一的 GID —— 跟UID類似,在系統上這是個唯一的數值。除了GID,每個組還有唯一的組名。Linux系統上有一些組工具可以創建和管理自己的組。
7.2.1 /etc/group 文件
-----------------------------------------------------------------------------------------------------------------------------------------
與用戶賬戶類似,組信息也保存在系統的一個文件中。/etc/group 文件包含系統上用到的每個組的信息。
[root@devalone ~]# cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:
cdrom:x:11:
mail:x:12:
devalone:x:1000:
saned:x:978:
stapusr:x:156:
stapsys:x:157:
stapdev:x:158:
systemd-coredump:x:977:
ntp:x:38:
user1:x:1001:
...
和 UID 一樣,GID 在分配時也採用了特定的格式。系統賬戶用的組通常會分配低於 500 的 GID 值,而用戶組的 GID 則會從 500 開始分配。/etc/group
文件有4個字段(CentOS 7 從 1000 開始分配 GID):
□ 組名
□ 組密碼
□ GID
□ 屬於該組的用戶列表
千萬不能通過直接修改 /etc/group 文件來添加用戶到一個組,要用 usermod 命令。在添加用戶到不同的組之前,首先得創建組。
7.2.2 創建新組
-----------------------------------------------------------------------------------------------------------------------------------------
groupadd 命令可在系統上創建新組。
[root@devalone ~]# groupadd shared
[root@devalone ~]# tail /etc/group
saned:x:978:
stapusr:x:156:
stapsys:x:157:
stapdev:x:158:
systemd-coredump:x:977:
hudson:x:976:
gitgroup:x:1003:devalone
ntp:x:38:
user1:x:1001:
shared:x:1004:
在創建新組時,默認沒有用戶被分配到該組。groupadd 命令沒有提供將用戶添加到組中的選項,但可以用 usermod 命令來彌補這一點。
[root@devalone ~]# usermod -G shared user1
[root@devalone ~]# tail -5 /etc/group
hudson:x:976:
gitgroup:x:1003:devalone
ntp:x:38:
user1:x:1001:
shared:x:1004:user1
shared 組現在有一個新成員:user1。usermod 命令的 -G 選項會把這個新組添加到該用戶賬戶的組列表裏。
7.2.3 修改組
-----------------------------------------------------------------------------------------------------------------------------------------
在 /etc/group 文件中可以看到,需要修改的組信息並不多。groupmod 命令可以修改已有組的GID(加-g選項)或組名(加-n選項)。
[root@devalone ~]# groupmod -n sharing shared
[root@devalone ~]# tail /etc/group
stapusr:x:156:
stapsys:x:157:
stapdev:x:158:
systemd-coredump:x:977:
hudson:x:976:
gitgroup:x:1003:devalone
ntp:x:38:
user1:x:1001:
test:x:1002:
sharing:x:1004:user1
修改組名時,GID 和組成員不會變,只有組名改變。由於所有的安全權限都是基於 GID 的,可以隨意改變組名而不會影響文件的安全性。
7.3 理解文件權限
-----------------------------------------------------------------------------------------------------------------------------------------
7.3.1 使用文件權限符
-----------------------------------------------------------------------------------------------------------------------------------------
[devalone@devalone shell-script]$ ll
總用量 108
drwxrwxr-x. 2 devalone devalone 4096 1月 2 2018 12
drwxrwxr-x. 2 devalone devalone 4096 1月 2 2018 13
drwxrwxr-x. 2 devalone devalone 4096 1月 7 13:15 14
drwxrwxr-x. 2 devalone devalone 4096 1月 7 13:15 15
drwxrwxr-x. 2 devalone devalone 4096 7月 2 19:32 dirsh
drwxr-xr-x. 2 devalone devalone 4096 7月 2 19:26 network-scripts-zz
-rwxrwxr-x. 1 devalone devalone 152 1月 2 2018 test1.sh
-rwxrwxr-x. 1 devalone devalone 123 1月 2 2018 test2.sh
-rwxrwxr-x. 1 devalone devalone 159 1月 2 2018 test3.sh
-rwxrwxr-x. 1 devalone devalone 123 1月 2 2018 test4.sh
-rwxrwxr-x. 1 devalone devalone 68 1月 2 2018 test5.sh
-rw-rw-r--. 1 devalone devalone 72 7月 2 20:08 testfile
輸出結果的第一個字段就是描述文件和目錄權限的編碼。這個字段的第一個字符代表了對象的類型:
- 代表文件
d 代表目錄
l 代表鏈接
c 代表字符型設備
b 代表塊設備
n 代表網絡設備
之後有 3 組三字符的編碼。每一組定義了 3 種訪問權限:
r 代表對象是可讀的
w 代表對象是可寫的
x 代表對象是可執行的
若沒有某種權限,在該權限位會出現單連字符 "-" 。這 3 組權限分別對應對象的 3 個安全級別:
□ 對象的屬主
□ 對象的屬組
□ 系統其他用戶
7.3.2 默認文件權限
-----------------------------------------------------------------------------------------------------------------------------------------
這些文件權限從何而來,答案是 umask。umask 命令用來設置所創建文件和目錄的默認權限。
[devalone@devalone shell-script]$ touch newfile
[devalone@devalone shell-script]$ ls -al newfile
-rw-r--r--. 1 devalone devalone 0 7月 4 16:16 newfile
touch 命令用分配給我的用戶賬戶的默認權限創建了這個文件。umask 命令可以顯示和設置這個默認權限。
[devalone@devalone shell-script]$ umask
0022
四位數的第一位代表了一項特別的安全特性,叫作粘着位(sticky bit)。後面的 3 位表示文件或目錄對應的 umask 八進制值。
八進制模式的安全性設置先獲取這3個 rwx 權限的值,然後將其轉換成3位二進制值,用一個八進制值來表示。
Linux文件權限碼:
+-----------+---------------+-----------+-----------------------
| 權 限 | 二進制值 | 八進制值 | 描 述
+-----------+---------------+-----------+-----------------------
| --- | 000 | 0 | 沒有任何權限
+-----------+---------------+-----------+-----------------------
| --x | 001 | 1 | 只有執行權限
+-----------+---------------+-----------+-----------------------
| -w- | 010 | 2 | 只有寫入權限
+-----------+---------------+-----------+-----------------------
| -wx | 011 | 3 | 有寫入和執行權限
+-----------+---------------+-----------+-----------------------
| r-- | 100 | 4 | 只有讀取權限
+-----------+---------------+-----------+-----------------------
| r-x | 101 | 5 | 有讀取和執行權限
+-----------+---------------+-----------+-----------------------
| rw- | 110 | 6 | 有讀取和寫入權限
+-----------+---------------+-----------+-----------------------
| rwx | 111 | 7 | 有全部權限
+-----------+---------------+-----------+-----------------------
八進制模式先取得權限的八進制值,然後再把這三組安全級別(屬主、屬組和其他用戶)的八進制值順序列出。因此,八進制模式的值 664 代表屬主和屬組
成員都有讀取和寫入的權限,而其他用戶都只有讀取權限。
umask值只是個掩碼。它會屏蔽掉不想授予該安全級別的權限。要把 umask 值從對象的全權限值中減掉。對文件來說,全權限的值是666(所有用戶都有讀
和寫的權限);而對目錄來說,則是777(所有用戶都有讀、寫、執行權限)。
所以在上例中,文件一開始的權限是 666,減去 umask值 022之後,剩下的文件權限就成了 644。
7.4 改變安全性設置
-----------------------------------------------------------------------------------------------------------------------------------------
7.4.1 改變權限
-----------------------------------------------------------------------------------------------------------------------------------------
chmod 命令用來改變文件和目錄的安全性設置。該命令的格式如下:
chmod options mode file
mode 參數可以使用八進制模式或符號模式進行安全性設置。八進制模式設置非常直觀,直接用期望賦予文件的標準3位八進制權限碼即可。
[devalone@devalone shell-script]$ chmod 760 newfile
[devalone@devalone shell-script]$ ls -l newfile
-rwxrw----. 1 devalone devalone 0 7月 4 16:16 newfile
八進制文件權限會自動應用到指定的文件上。
與通常用到的3組三字符權限字符不同,chmod 命令採用了另一種方法。下面是在符號模式下指定權限的格式:
[ugoa…][[+-=][rwxXstugo…]
第一組字符定義了權限作用的對象:
u 代表用戶
g 代表組
o 代表其他
a 代表上述所有
下一步,後面跟着的符號表示是想在現有權限基礎上增加權限(+),還是在現有權限基礎上移除權限(),或是將權限設置成後面的值(=)。
最後,第三個符號代表作用到設置上的權限。這個值要比通常的 rwx 多。額外的設置有以下幾項:
X:如果對象是目錄或者它已有執行權限,賦予執行權限。
s:運行時重新設置UID或GID。
t:保留文件或目錄。
u:將權限設置爲跟屬主一樣。
g:將權限設置爲跟屬組一樣。
o:將權限設置爲跟其他用戶一樣。
示例:給其它用戶增加讀取權限
[devalone@devalone shell-script]$ ls -l newfile
-rwxrw----. 1 devalone devalone 0 7月 4 16:16 newfile
[devalone@devalone shell-script]$ chmod o+r newfile
[devalone@devalone shell-script]$ ls -l newfile
-rwxrw-r--. 1 devalone devalone 0 7月 4 16:16 newfile
示例:將屬主已有的執行權限移除
[devalone@devalone shell-script]$ chmod u-x newfile
[devalone@devalone shell-script]$ ls -l newfile
-rw-rw-r--. 1 devalone devalone 0 7月 4 16:16 newfile
options 爲 chmod 命令提供了另外一些功能。-R 選項可以讓權限的改變遞歸地作用到文件和子目錄。可以使用通配符指定多個文件,然後利用一條命令
將權限更改應用到這些文件上。
7.4.2 改變所屬關係
-----------------------------------------------------------------------------------------------------------------------------------------
有時需要改變文件的屬主,Linux提供了兩個命令來實現這個功能:chown 命令用來改變文件的屬主,chgrp 命令用來改變文件的默認屬組。
chown命令的格式如下:
chown options owner[:group] file
可用登錄名或 UID 來指定文件的新屬主:
[root@devalone shell-script]# chown user1 newfile
[root@devalone shell-script]# ls -l newfile
-rw-rw-r--. 1 user1 devalone 0 7月 4 16:16 newfile
chown 命令也支持同時改變文件的屬主和屬組:
[root@devalone shell-script]# chown user1:sharing newfile
[root@devalone shell-script]# ls -l newfile
-rw-rw-r--. 1 user1 sharing 0 7月 4 16:16 newfile
可以只改變一個目錄的默認屬組:
[root@devalone shell-script]# chown :devalone newfile
[root@devalone shell-script]# ls -l newfile
-rw-rw-r--. 1 user1 devalone 0 7月 4 16:16 newfile
如果 Linux 系統採用和用戶登錄名匹配的組名,可以只用一個條目就改變二者。
[root@devalone shell-script]# chown devalone: newfile
[root@devalone shell-script]# ls -l newfile
-rw-rw-r--. 1 devalone devalone 0 7月 4 16:16 newfile
chown 命令採用一些不同的選項參數。-R 選項配合通配符可以遞歸地改變子目錄和文件的所屬關係。-h 選項改變該文件的所有符號鏈接文件的所屬關係。
NOTE:
-------------------------------------------------------------------------------------------------------------------------------------
只有 root 用戶能夠改變文件的屬主。任何屬主都可以改變文件的屬組,但前提是屬主必須是原屬組和目標屬組的成員。
chgrp 命令可以更改文件或目錄的默認屬組:
[root@devalone shell-script]# chgrp sharing newfile
[root@devalone shell-script]# ls -l newfile
-rw-rw-r--. 1 devalone sharing 0 7月 4 16:16 newfile
用戶賬戶必須是這個文件的屬主,除了能夠更換屬組之外,還得是新組的成員。現在 sharing 組的任意一個成員都可以寫這個文件了。這是 Linux 系統
共享文件的一個途徑。
7.5 共享文件
-----------------------------------------------------------------------------------------------------------------------------------------
inux系統上共享文件的方法是創建組。創建新文件時,Linux 會用登錄賬戶默認的 UID 和 GID 給文件分配權限。想讓其他人也能訪問文件,要麼改變其他
用戶所在安全組的訪問權限,要麼就給文件分配一個包含其他用戶的新默認屬組。
Linux 還爲每個文件和目錄存儲了3個額外的信息位。
□ 設置用戶ID(SUID):當文件被用戶使用時,程序會以文件屬主的權限運行。
□ 設置組ID(SGID) :對文件來說,程序會以文件屬組的權限運行;對目錄來說,目錄中創建的新文件會以目錄的默認屬組作爲默認屬組。
□ 粘着位 :進程結束後文件還駐留(粘着)在內存中。
SGID 位對文件共享非常重要。啓用 SGID 位後,可以強制在一個共享目錄下創建的新文件都屬於該目錄的屬組,這個組也就成爲了每個用戶的屬組。
SGID 可通過 chmod 命令設置。它會加到標準3位八進制值之前(組成4位八進制值),或者在符號模式下用符號s。
如果用的是八進制模式,需要知道這些位的位置,如下表:
chmod SUID、SGID 和粘着位的八進制值:
+-----------+-----------+---------------------------------------------------------------
| 二進制值 | 八進制值 | 描 述
+-----------+-----------+---------------------------------------------------------------
| 000 | 0 | 所有位都清零
+-----------+-----------+---------------------------------------------------------------
| 001 | 1 | 粘着位置位
+-----------+-----------+---------------------------------------------------------------
| 010 | 2 | SGID位置位
+-----------+-----------+---------------------------------------------------------------
| 011 | 3 | SGID位和粘着位都置位
+-----------+-----------+---------------------------------------------------------------
| 100 | 4 | SUID位置位
+-----------+-----------+---------------------------------------------------------------
| 101 | 5 | SUID位和粘着位都置位
+-----------+-----------+---------------------------------------------------------------
| 110 | 6 | SUID位和SGID位都置位
+-----------+-----------+---------------------------------------------------------------
| 111 | 7 | 所有位都置位
+-----------+-----------+---------------------------------------------------------------
因此,要創建一個共享目錄,使目錄裏的新文件都能沿用目錄的屬組,只需將該目錄的 SGID 位置位。
[root@devalone shell-script]# mkdir testdir
[root@devalone shell-script]# ll testdir
總用量 0
[root@devalone shell-script]# ll -d testdir
drwxr-xr-x. 2 root root 4096 7月 4 17:10 testdir
[root@devalone shell-script]# chgrp sharing testdir
[root@devalone shell-script]# ll -d testdir
drwxr-xr-x. 2 root sharing 4096 7月 4 17:10 testdir
[root@devalone shell-script]# chmod g+s testdir
[root@devalone shell-script]# ll -d testdir
drwxr-sr-x. 2 root sharing 4096 7月 4 17:10 testdir
[root@devalone shell-script]# umask 002
[root@devalone shell-script]# cd testdir
[root@devalone testdir]# ll
總用量 0
[root@devalone testdir]# touch testfile
[root@devalone testdir]# ll
總用量 0
-rw-rw-r--. 1 root sharing 0 7月 4 17:12 testfile
用 mkdir 命令來創建希望共享的目錄。然後通過 chgrp 命令將目錄的默認屬組改爲包含所有需要共享文件的用戶的組(必須是該組的成員)。最後,將
目錄的 SGID 位置位,以保證目錄中新建文件都用 sharing 作爲默認屬組。
爲了讓這個環境能正常工作,所有組成員都需把他們的 umask 值設置成文件對屬組成員可寫。umask 改成了002,所以文件對屬組是可寫的。
做完了這些,組成員就能到共享目錄下創建新文件了。跟期望的一樣,新文件會沿用目錄的屬組,而不是用戶的默認屬組。現在 sharing 組的所有用戶都能
訪問這個文件了。
8. 管理文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
使用 Linux 系統時,需要作出的重大決策之一就是爲存儲設備選用什麼文件系統。
8.1 探索Linux 文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 支持多種類型的文件系統管理文件和目錄。每種文件系統都在存儲設備上實現了虛擬目錄結構,僅特性有所不同。
8.1.1 基本的Linux 文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 最初採用的是一種簡單的文件系統,它模仿了 Unix 文件系統的功能。
■ ext 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
Linux 操作系統中引入的最早的文件系統叫作擴展文件系統(extended filesystem,簡記爲ext)。它爲 Linux 提供了一個基本的類 Unix文件系統:
使用虛擬目錄來操作硬件設備,在物理設備上按定長的塊來存儲數據。
■ ext2 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
最早的 ext 文件系統有不少限制,比如文件大小不得超過 2GB。在 Linux 出現後不久,ext文件系統就升級到了第二代擴展文件系統,叫作 ext2。
ext2 文件系統是 ext 文件系統基本功能的一個擴展,但保持了同樣的結構。ext2 文件系統擴展了索引節點表的格式來保存系統上每個文件的更多信息。
ext2 的索引節點表爲文件添加了創建時間值、修改時間值和最後訪問時間值來幫助系統管理員追蹤文件的訪問情況。ext2文件系統還將允許的最大文件
大小增加到了2 TB(在ext2的後期版本中增加到了32 TB),以容納數據庫服務器中常見的大文件。
除了擴展索引節點表外,ext2 文件系統還改變了文件在數據塊中存儲的方式。ext 文件系統常見的問題是在文件寫入到物理設備時,存儲數據用的塊
很容易分散在整個設備中(稱作碎片化,fragmentation)。數據塊的碎片化會降低文件系統的性能,因爲需要更長的時間在存儲設備中查找特定文件的
所有塊。
保存文件時,ext2 文件系統通過按組分配磁盤塊來減輕碎片化。通過將數據塊分組,文件系統在讀取文件時不需要爲了數據塊查找整個物理設備。
8.1.2 日誌文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
日誌文件系統爲 Linux 系統增加了一層安全性。它不再使用之前先將數據直接寫入存儲設備再更新索引節點表的做法,而是先將文件的更改寫入到臨時文件
(稱作日誌,journal)中。在數據成功寫到存儲設備和索引節點表之後,再刪除對應的日誌條目。如果系統在數據被寫入存儲設備之前崩潰或斷電了,日誌
文件系統下次會讀取日誌文件並處理上次留下的未寫入的數據。
■ ext3 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
2001年,ext3 文件系統被引入 Linux 內核中。它採用和 ext2 文件系統相同的索引節點表結構,但給每個存儲設備增加了一個日誌文件,以將準備寫入
存儲設備的數據先記入日誌。
默認情況下,ext3 文件系統用有序模式的日誌功能——只將索引節點信息寫入日誌文件,直到數據塊都被成功寫入存儲設備才刪除。用戶可以在創建文件
系統時用簡單的一個命令行選項將 ext3 文件系統的日誌方法改成數據模式或回寫模式。
■ ext4 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
擴展 ext3 文件系統功能的結果是 ext4 文件系統。ext4 文件系統在 2008 年受到 Linux 內核官方支持,現在已是大多數流行的 Linux 發行版採用的
默認文件系統。
除了支持數據壓縮和加密,ext4 文件系統還支持一個稱作區段(extent)的特性。區段在存儲設備上按塊分配空間,但在索引節點表中只保存起始塊的
位置。由於無需列出所有用來存儲文件中數據的數據塊,它可以在索引節點表中節省一些空間。
ext4 還引入了塊預分配技術(block preallocation)。如果想在存儲設備上給一個知道要變大的文件預留空間,ext4 文件系統可以爲文件分配所有需
要用到的塊,而不僅僅是那些現在已經用到的塊。ext4 文件系統用 0 填滿預留的數據塊,不會將它們分配給其他文件。
■ Reiser 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
2001年,Hans Reiser 爲 Linux 創建了第一個稱爲 ReiserFS 的日誌文件系統。ReiserFS 文件系統只支持回寫日誌模式——只把索引節點表數據寫到日誌
文件。ReiserFS 文件系統也因此成爲 Linux 上最快的日誌文件系統之一。
■ JFS 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
作爲可能依然在用的最老的日誌文件系統之一,JFS(Journaled File System,日誌化文件系統)是 IBM 在1990年爲其 Unix 衍生版 AIX 開發的。然而
直到第2版,它才被移植到 Linux 環境中。
JFS 文件系統採用的是有序日誌方法,即只在日誌中保存索引節點表數據,直到真正的文件數據被寫進存儲設備時才刪除它。這個方法在 ReiserFS 的速
度和數據模式日誌方法的完整性之間的採取的一種折中。
■ XFS 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
XFS 日誌文件系統是另一種最初用於商業 Unix 系統而如今走進 Linux 世界的文件系統。美國硅圖公司(SGI)最初在1994年爲其商業化的 IRIX Unix
系統開發了 XFS。2002年,它被髮布到了適用於 Linux 環境的版本。
XFS 文件系統採用回寫模式的日誌,在提供了高性能的同時也引入了一定的風險,因爲實際數據並未存進日誌文件。XFS 文件系統還允許在線調整文件
系統的大小,XFS 文件系統只能擴大不能縮小。
8.1.3 寫時複製文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
就文件系統而言,日誌式的另一種選擇是一種叫作寫時複製(copy-on-write,COW)的技術。COW 利用快照兼顧了安全性和性能。如果要修改數據,會使用
克隆或可寫快照。修改過的數據並不會直接覆蓋當前數據,而是被放入文件系統中的另一個位置上。即便是數據修改已經完成,之前的舊數據也不會被重寫。
■ ZFS 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
COW 文件系統 ZFS 是由 Sun公司於 2005年研發的,用於 OpenSolaris 操作系統,從2008年起開始向 Linux移植,最終在2012年投入Linux產品的使用。
ZFS 是一個穩定的文件系統,與 Resier4、Btrfs 和 ext4勢均力敵。它最大的弱項就是沒有使用 GPL 許可。自2013年發起的 OpenZFS 項目有可能改變
這種局面。
■ Btrf 文件系統
-------------------------------------------------------------------------------------------------------------------------------------
Btrfs 文件系統是 COW 的新人,也被稱爲 B 樹文件系統。它是由 Oracle公司於2007年開始研發的。Btrfs 在 Reiser4 的諸多特性的基礎上改進了
可靠性。另一些開發人員最終也加入了開發過程,幫助 Btrfs 快速成爲了最流行的文件系統。究其原因,則要歸於它的穩定性、易用性以及能夠動態
調整已掛載文件系統的大小。OpenSUSE Linux 發行版最近將 Btrfs 作爲其默認文件系統。除此之外,該文件系統也出現在了其他 Linux 發行版中(
如 RHEL),不過並不是作爲默認文件系統。
8.2 操作文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 提供了一些不同的工具,可以利用它們輕鬆地在命令行中進行文件系統操作。可使用鍵盤隨心所欲地創建新的文件系統或者修改已有的文件系統。
8.2.1 創建分區
-----------------------------------------------------------------------------------------------------------------------------------------
一開始,必須在存儲設備上創建分區來容納文件系統。分區可以是整個硬盤,也可以是部分硬盤,以容納虛擬目錄的一部分。
fdisk 工具用來幫助管理安裝在系統上的任何存儲設備上的分區。它是個交互式程序,允許輸入命令來逐步完成硬盤分區操作。
要啓動 fdisk 命令,必須指定要分區的存儲設備的設備名,另外還得有超級用戶權限。
$ sudo fdisk /dev/sdb
[sudo] password for Christine:
Device contains neither a valid DOS partition table,
nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xd3f759b5.
Changes will remain in memory only
until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will
be corrected by w(rite)
[...]
Command (m for help):
fdisk 交互式命令提示符使用單字母命令來告訴 fdisk 做什麼:輸入 m 獲得命令幫助。
可以用 p 命令將一個存儲設備的詳細信息顯示出來:
Command (m for help): p
Disk /dev/sdb: 5368 MB, 5368709120 bytes
255 heads, 63 sectors/track, 652 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x11747e88
Device Boot Start End Blocks Id System
Command (m for help):
可以使用n命令在該存儲設備上創建新的分區。
Command (m for help): n
Command action
e extended
p primary partition (1-4)
分區可以按主分區(primary partition)或擴展分區(extended partition)創建。主分區可以被文件系統直接格式化,而擴展分區則只能容納其他主分區。
擴展分區出現的原因是每個存儲設備上只能有 4 個分區。可以通過創建多個擴展分區,然後在擴展分區內創建邏輯分區進行擴展。
創建了想要的分區之後,用 w 命令將更改保存到存儲設備上。
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
存儲設備的分區信息被寫入分區表中,Linux 系統通過 ioctl() 調用來獲知新分區的出現。設置好分區之後,可以使用 Linux文件系統對其進行格式化。
8.2.2 創建文件系統
-----------------------------------------------------------------------------------------------------------------------------------------
在將數據存儲到分區之前,必須用某種文件系統對其進行格式化,這樣 Linux 才能使用它。每種文件系統類型都用自己的命令行程序來格式化分區。
命令:mkfs
用法:
mkfs [-t 文件系統格式] 設備
mkfs [選項] [-t <類型>] [文件系統選項] <設備> [<大小>]
選項與參數:
-t :後接文件系統格式,如:xfs, ext4, ext3, ext2, vfat 等(只有系統支持纔會生效)
設備: 指分區的設備文件絕對路徑,如:/dev/sdc1
範例:使用 xfs 格式化分區 /dev/sdc1
mkfs -t xfs /dev/sdc1
執行下面指令:
-------------------------------------------------------------------------------------------------------------------------------------
[root@www ~]# mkfs[tab][tab] <==按兩個[tab]
結果:
mkfs mkfs.cramfs mkfs.ext3 mkfs.fat mkfs.msdos mkfs.xfs
mkfs.btrfs mkfs.ext2 mkfs.ext4 mkfs.minix mkfs.vfat
說明: mkfs 實際上是一個綜合指令,執行時會根據不同的文件系統格式類型選擇對應的格式化工具執行格式化任務。例如 mkfs -t xfs, 實際執行的是
mkfs.xfs 工具命令。
vfat 可用於 Windows/Linux 共享的 U 盤或移動硬盤文件格式。
8.2.3 文件系統的檢查與修復
-----------------------------------------------------------------------------------------------------------------------------------------
fsck 命令能夠檢查和修復大部分類型的 Linux 文件系統。
用法:
fsck [-t 文件系統] [-ACay] [filesys ... ] [--] [ fs-specific-options ]
選項與參數:
-t :如同 mkfs 一樣,fsck 也是個綜合軟件,因此同樣需要指定文件系統。 不過由於現在的 Linux 很智能,它會通過 superblock 自動判斷文件系統,
因此通常可以省略該選項。
-A :根據 /etc/fstab 的內容,將需要的設備掃瞄一次。通常開機過程會執行此命令。
-a :自動修復檢查到的有問題的扇區,所以不用一直按 y 鍵。
-y :與 -a 類似,但是某些 filesystem 僅支持 -y 這個參數。
-C :可以在檢查過程當中,使用一個直方圖來顯示當前進度。
filesys ... : 可以是一個設備名(例如: /dev/hdc1, /dev/sdb2), 一個掛載點(例如: /, /usr, /home), 或一個ext2文件系統的磁盤標籤, 也可以是UUID
指定符(例如: UUID=8868abf6-88c5-4a83-98b8-bfc24057f7bd 或 LABEL=root). 通常,fsck 會試着以並行的方式同時在不同的物理磁盤上運行文件系統
檢查,這樣可以減少對所有文件系統進行檢查的時間。
如果沒有在命令行指定文件系統,並且沒有指定 -A 選項,fsck 將默認順序地檢查 /etc/fstab 中登記的文件系統。這和使用 -As 選項是相同的。
執行:
-----------------------------------------------------------------------------------------------------------------------------------------
[root@www ~]# fsck[tab][tab] <==按兩個[tab]
結果:
fsck fsck.cramfs fsck.ext3 fsck.fat fsck.msdos fsck.xfs
fsck.btrfs fsck.ext2 fsck.ext4 fsck.minix fsck.vfat
說明:
實際上,fsck 只是 Linux 中不同的文件系統檢查器(fsck.fstype)的一個前端。首先,它在 /sbin 中搜索特定文件系統的檢查器,然後在 /etc/fs 和
/etc 中搜索,最後在 PATH 環境變量中列出的路徑中搜索。
執行 fsck 時,被檢查 partition 分區不可掛載到系統上,亦即需要在卸載狀態下。
(本篇完)
參考:
《Linux 命令行與 shell 腳本編程大全》 第 3 版 —— 2016.8(美)Richard Blum Cristine Bresnahan