# Linux (三) - 檔案的基本屬性與權限 在 [Linux (一) - 基本概念與系統操作](https://tienyulin.github.io/linux-basic-concept-command/) 有提到,Linux 支援多使用者同時進行操作。多個使用者可以同時進行操作雖然是非常方便,但是卻也因此衍生出了檔案權限的安全性問題。所以 Linux 系統對於不同使用者要存取相同的檔案或目錄都有不同的權限設定。 <!-- more --> ## 檔案屬性 [上一篇](https://tienyulin.github.io/linux-filesystem/) 我們有介紹過了 ls 指令可以列出目錄下的檔案和目錄,這裡我們要在使用 `ls -l` 列出檔案的詳細資訊來查看檔案的屬性。如下 : ```bash= $ ls -l total 56 -rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin drwxr-xr-x 5 root root 360 Sep 24 06:05 dev drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc ... ``` 從上面列出的資訊可以看到最左邊的欄位就是檔案的屬性,仔細看可以發現這一欄其實有 10 個屬性。 第一個屬性代表這個檔案是`目錄`、`檔案`或是`連結檔`,分別以 `d`、`-`、`l` 表示。 而比較少用的還有外接裝置的文件檔案,`可以隨機存取的裝置`以 `b` 表示,一次性讀取的設備 (滑鼠、鍵盤) 則以 `c` 表示。 接下來的九個屬性代表的都是權限,分別以三個為一組,每一組都是 `rwx` 三個參數組合,`r` 代表可以讀取、`w` 代表可以寫入、`x` 代表可以執行。第一組代表檔案擁有者的權限、第二組代表擁有者群組的權限、第三組代表其他使用者的權限。如果沒有該項權限則會用 `-` 表示。 **範例** 有一個檔案的屬性為 `-rwxr-xr--`,我們先用中括號將代表不同意義的屬性分開,如下 : ``` [-][rwx][r-x][r--] ``` 上面用中括號分開後就可以很清楚的看懂這個檔案的屬性了,首先 `-` 代表這是一個檔案,接著 `rwx` 代表這個檔案的擁有者可以 `讀、寫、執行`。再往下一個 `r-x` 代表跟擁有者隸屬同一個群組的使用者可以 `讀、執行`,最後一個 `r--` 代表其他使用者只可以 `讀`。 而如果是 root 的話有非常大的權限,基本上都是可讀、可寫、可執行的,所以在 [Linux (一) - 基本概念與系統操作](https://tienyulin.github.io/linux-basic-concept-command/) 有提到盡量不要直接使用 root 做事,一不小心就會把檔案改壞造成系統出問題。 ## 更改檔案屬性與權限 前面介紹完了檔案的屬性,現在就要來介紹要如何更改檔案的屬性和權限。 ### 更改檔案所屬的群組 (chgrp) `chgrp` (change group) 指令可以用來更改檔案所屬的群組。 ```bash= $ chgrp [-R] <group> <file/directory> ``` `-R` 是一個選擇性的參數,如果有加的話會將目錄下所有檔案的所屬群組都改掉。 這裡要注意一點,如果要更改的群組沒有在 `/etc/group` 這個檔案中定義的話是會更改失敗的,所以在更改前要注意有沒有定義這個群組。 **範例** 這個範例先用 `touch` 指令建立一個測試用的檔案,接著再使用 `chgrp` 指令進行群組更改。 ```bash= // 建立測試檔案 $ touch test.txt $ ls -l test.txt -rw-r--r-- 1 user1 group1 0 Sep 29 07:15 test.txt $ chgrp group2 test.txt $ ls -l test.txt -rw-r--r-- 1 user1 group2 0 Sep 29 07:15 test.txt ``` 接著我們再示範加上 `-R` 參數一次修改目錄下所有檔案的群組,如下 : ```bash= // 建立測試資料夾 $ mkdir testDir $ cd testDir // 建立兩個測試檔案 $ touch testFile1 testFile2 $ ls -l total 0 -rw-r--r-- 1 user1 group1 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user1 group1 0 Sep 29 07:32 testFile2 $ cd ../ // 更改資料夾下所有檔案的群組 $ chgrp -R group2 testDir // 更改完成 $ ls -l testDir total 0 -rw-r--r-- 1 user1 group2 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user1 group2 0 Sep 29 07:32 testFile2 ``` ### 更改檔案擁有者 (chown) `chown` (change owner) 指令可以用於更改檔案的擁有者。 ```bash= $ chown [-R] <account> <file/directory> $ chown [-R] <account>:<group> <file/directory> ``` `-R` 同樣是一個選擇性的參數,如果有加的話會將目錄下所有檔案的擁有者都改掉。 `chown` 還可以順便更改群組,方式是上面指令的第二種方式。 這裡要注意一點,如果要更改的帳後沒有在 `/etc/passwd` 這個檔案中定義的話是會更改失敗的,所以在更改前要注意這個帳號是否存在。 **範例** 這個範例使用前面建立的 `testFile1` 來測試,可以看到最後擁有者從 `user1` 被改成了 `user2`。 ```bash= $ ls -l total 0 -rw-r--r-- 1 user1 group2 0 Sep 29 07:32 testFile1 $ chown user2 testFile1 $ ls -l total 0 -rw-r--r-- 1 user2 group2 0 Sep 29 07:32 testFile1 ``` 下面這個範例一次更改了檔案的擁有者和群組,可以看到最後擁有者和群組分別從 `user2`、`group2` 被換成了 `user1`、`group1`。 ```bash= $ ls -l total 0 -rw-r--r-- 1 user2 group2 0 Sep 29 07:32 testFile1 $ chown user1:group1 testFile1 $ ls -l total 0 -rw-r--r-- 1 user1 group1 0 Sep 29 07:32 testFile1 ``` 最後同樣再加上 `-R` 來一次更改整個目錄下所有檔案的擁有者,可以看到兩個檔案的擁有者都從 `user1` 被改成了 `user2`。 ```bash= $ ls -l total 0 -rw-r--r-- 1 user1 group1 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user1 group2 0 Sep 29 07:32 testFile2 $ cd ../ $ chown -R user2 testDir $ ls -l testDir total 0 -rw-r--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user2 group2 0 Sep 29 07:32 testFile2 ``` ### 更改檔案權限 (chmod) `chmod` (change mode) 可以用於更改檔案的權限。更改的方式有兩種,分別是數字和符號。 ```bash= chmod [option] mode[,mode] <file> ``` option : * `-R` : 這裡的 `-R` 和前面介紹的一樣,可以直接更該整個目錄下的所有檔案 mode 可以指定要更改成的檔案權限,分別會對應到以數字或是符號的方法,下面會再詳細介紹。 #### 數字更改 上面有介紹了權限會有九個屬性,分別是 `owner/group/others` 三種身分以及它們各自的 `read/write/execute` 權限。 `rwx` 權限如果都有,以二進位來表示就是 `111`,而 `111` 轉換成 10 進位就是 `7`。如果是 `r-x`,以二進位表示就是 `101`,轉換成 10 進位就是 `5`。 如果對於二進位不熟悉的話可以先把每個權限對應到一個數字,再將有權限的數字加起來,如下 : * r : 4 * w : 2 * x : 1 所以再套用到上面的範例,`rwx` 是 `4+2+1=7`,而 `r-x` 是 `4+0+1=5`。其實二進位的算法也是這樣,只是如果你不了解二進位那就先背起來這些數字或是直接去了解一下什麼是二進位。 再回到前面權限的定義,總共會有三組的 `read/write/execute`,所以就可以將每一組的數字算出來之後合在一起,例如權限為 `rwxr-xr--`,則計算方式如下 : * owner = rwx = 4+2+1 = 7 * group = r-x = 4+0+1 = 5 * others = r-- = 4+0+0 = 4 將以上算完的數字依照 `owner/group/others` 的順序合在一起就是 `754`。這裡得出的數值就是 `chmod` 指令要指定的 `mode`,例如 : ```bash= chmod 754 testFile.txt ``` #### 符號更改 我們已經知道權限是由 `owner/group/others` 三種身分組成,這裡我們將 `owner` 先換成 `user` 以便對應後面的符號定義。所以符號的定義就是透過 `u`、`g`、`o` 分別指定`user/group/others` 的權限。 例如要指定 `user` 的權限是 `rwx`,就在 `chmod` 指令的 `mode` 代入 `u=rwx`。如果要指定 `group/others` 為同一個權限 `r-x`,可以代入 `go=rx`。 如果要同時設定不同的身分不同的權限,可以連續指定 `mode`,以逗號隔開,例如 : ```bash= chmod u=rwx,go=rx testFile.txt ``` 除了一個一個指定,還有一個符號可以一次設定所有的身分,就是 `a`,所以以下兩種方式會是相同的結果 : ```bash= chmod a=rwx chmod ugo=rwx ``` 上面介紹了用 `ugoa` 四個符號搭配 `=` 就可以指定權限,而如果原先並不知道檔案的權限只是想要新增或去除某項權限,就可以透過 `+` 和 `-` 兩個符號直接指定,不需要再去查檔案的權限。例如現在要去除 `user` 的 `write` 權限並且新增 `others` 的 `execute` 權限,則做法如下 : ```bash= chmod u-w,o+x testFile.txt ``` #### 範例 先使用數字的方式更改,針對 `testFile1` 指定 `777`,也就是所有權限打開,可以看到 `testFile1` 更改後變成 `-rwxrwxrwx`。而 `testFile2` 指定 `750`,就是 `owner` 有所有權限、`group` 有讀和執行的權限、`others` 沒有任何權限,所以 `testFile2` 改完後變成 `-rwxr-x---`。 ```bash= $ ls -l total 0 -rw-r--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user2 group2 0 Sep 29 07:32 testFile2 $ chmod 777 testFile1 $ ls -l total 0 -rwxrwxrwx 1 user2 group1 0 Sep 29 07:32 testFile1 -rw-r--r-- 1 user2 group2 0 Sep 29 07:32 testFile2 $ chmod 750 testFile2 $ ls -l total 0 -rwxrwxrwx 1 user2 group1 0 Sep 29 07:32 testFile1 -rwxr-x--- 1 user2 group2 0 Sep 29 07:32 testFile2 ``` 我們換成用符號更改,首先指定 `testFile1` 的 `user` 有讀和執行的權限,`group` 和 `others` 只有讀的權限,更改完後屬性變成了 `-r-xr--r--`。 ```bash= $ ls -l total 0 -rwxrwxrwx 1 user2 group1 0 Sep 29 07:32 testFile1 -rwxr-x--- 1 user2 group2 0 Sep 29 07:32 testFile2 $ chmod u=rx,go=r testFile1 $ ls -l total 0 -r-xr--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -rwxr-x--- 1 user2 group2 0 Sep 29 07:32 testFile2 ``` 接著換用 `a` 這個符號來一次指定 `testFile2` 的所有身分都只有讀的權限,更改完後屬性變成了 `-r--r--r--`。 ```bash= $ ls -l total 0 -r-xr--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -rwxr-x--- 1 user2 group2 0 Sep 29 07:32 testFile2 $ chmod a=r testFile2 $ ls -l total 0 -r-xr--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -r--r--r-- 1 user2 group2 0 Sep 29 07:32 testFile2 ``` 最後我們用 `+` 和 `-` 來加入或移除權限,將 `testFile2` 的 `user` 的權限新增寫和執行的權限,`others` 移除讀的權限,更改完後屬性變成了 `-rwxr-----`。 ```bash= $ ls -l total 0 -r-xr--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -r--r--r-- 1 user2 group2 0 Sep 29 07:32 testFile2 $ chmod u+wx,o-r testFile2 $ ls -l total 0 -r-xr--r-- 1 user2 group1 0 Sep 29 07:32 testFile1 -rwxr----- 1 user2 group2 0 Sep 29 07:32 testFile2 ``` ## 檔案權限的用途 檔案權限對系統來說就是判斷使用者可不可以存取這個檔案,而對於一般的檔案和目錄,在 `rwx` 權限上的用途稍微有點不一樣。 | | r | w | x | | ---- | ------------------ | ---------------------- | ---------------- | | 檔案 | 可以讀到檔案內容 | 可以修改文件內容 | 可以執行文件內容 | | 目錄 | 可以讀到目錄下檔名 | 可以修改目錄下文件檔名 | 可以進入該目錄 | 對目錄來說有個比較有趣也需要特別注意的是 `x` 權限,上面有很清楚的寫了 `x` 是決定了是否可以進入該目錄。所以乍看 `r` 好像是可以進入這個目錄看到裡面的內容,實際上如果你沒有 `x` 的權限,就算有 `r` 或 `w` 都是沒有用的,因為沒有權限進入目錄更別提還可以存取了。 **範例** 下面這個範例將目錄的 `x` 權限移除,可以看到雖然有 `r` 和 `w` 的權限,但是在進入 `testDir` 的時候就被拒絕了。 ```bash= $ ls -l total 125868 drwxr-xr-x 2 user1 group1 6 Sep 30 03:12 testDir ... $ chmod a-x testDir $ ls -l total 125868 drw-r--r-- 2 user1 group1 6 Sep 30 03:12 testDir ... $ cd testDir bash: cd: testDir: Permission denied ``` ## Summary 檔案的屬性和權限設定非常重要,如果是公司的系統就一定要篩選過每個人有甚麼權限可以讀到甚麼類型的檔案,在資安上是有必要設定的。 除此之外,最常用在複製檔案給別人使用的時候。如果複製的檔案沒有改過屬性和權限的設定就有可能因為不同的系統或是使用者導致檔案不能使用。 ![image alt](http://turnoff.us/image/en/chown-chmod.png =302x436) ## 參考 [1] [Linux 檔案屬性 | 鳥站](https://linux.vbird.org/linux_basic/redhat6.1/linux_05file.php) [2] [Linux 文件基本屬性](https://www.runoob.com/linux/linux-file-attr-permission.html) [3] [Linux 的檔案權限與目錄配置](http://linux.vbird.org/linux_basic/0210filepermission.php) ###### tags: `Linux`