---
tags: Unix-like
---
# 檔案與目錄
[TOC]
檔案可存取的身份分為三種 owner / group / others,各有 read / write / execute 的權限。

## File Type
| File Type | Description |
|-----------|-------------|
| d | 目錄 |
| - | 檔案 |
| l | 連結檔 |
| b | 裝置檔裡面的可供儲存的周邊設備,例如硬碟、軟碟 |
| c | 裝置檔裡面的序列埠設備,例如鍵盤、滑鼠 |
| s | Socket |
| p | Pipe |
## Permissions

目錄權限說明:
* **R: Read contents in directory**
讀取目錄結構清單的權限,可以查詢該目錄下的檔名資料。
* **W: Modify contents of directory**
異動該目錄結構清單的權限,可以建立、刪除、更名搬移檔案與目錄。
* **X: Access directory**
進入該目錄成為工作目錄的權限。
### 預設權限 `umask`
```shell
$ umask # 第一個為特殊權限
0022
$ umask -S # Symbolic
u=rwx,g=rx,o=rx
$ umask 003 # 設定新值
```
數字代表**該預設值需要減掉的權限**,如上方 2 就代表拿掉 w 的權限。
| | 預設權限 | umask | 結果 |
|-----|---------|-------|-----|
| 檔案 | `-rw-rw-rw-` | `-----w--w-` | `-rw-r--r--` |
| 目錄 | `drwxrwxrwx` | `-----w--w-` | `drwxr-xr-x` |
### 特殊權限
#### SUID
特殊權限為 4,Set UID,在 user 的 x 權限為 **s**,**執行者將在執行該程式的過程中具有該程式 owner 的權限**。
* SUID 權限僅對 binary program 有效,不能夠用在 shell script
* 執行者對於該程式需要具有 x 的可執行權限
* 不可使用在目錄上
```shell
-r-s--x--x 1 root wheel 370720 May 4 2019 /usr/bin/sudo
```

#### SGID
特殊權限為 2,與 SUID 類似,在 group 的 x 權限為 **s**。
* 能夠用在目錄與檔案上
* 在此目錄下的 effective group 將會變成該目錄的群組,**該目錄下建立的檔案群組會為該目錄的群組**
> Find all SUID files:
>
> ```shell
> $ find / -perm -4000
> ```
>
> Find all SGID files:
>
> ```shell
> $ find / -perm -2000
> ```
#### SBIT
特殊權限為 1,Sticky Bit,Other 的 x 權限為 **t**。使用者在該目錄下建立檔案或目錄時,**僅有自己與 root 才有權力刪除該檔案**。
* 只針對目錄有效
* 使用者對於此目錄具有 wx 權限
舉例來說,`/tmp` 本身的權限是 `drwxrwxrwt`,任何人都可以在 `/tmp` 內新增、修改檔案,但僅有該檔案或目錄建立者與 root 能夠刪除自己的目錄或檔案。
#### 變更特殊權限
一般 `chmod` 只給三個數字,在最前方加上 SUID 4、SGID 2、SBIT 1 就可以加上特殊權限。如果沒有 x 權限,會變成大寫的 S、T 表示空權限。
```shell
$ chmod 4755
$ chmod u+s
$ chmod g+s
$ chmod o+t
```
## inode
檔案系統建立(格式化)時,就把儲存區域分為兩大連續的儲存區域。分別用來儲存檔案系統物件的元資訊資料、內容資料。而 inode 就是用來**儲存檔案系統物件的元資訊資料**。
由於每個檔案都必須有一個 inode,因此有可能發生 inode 已經用光,但是硬碟還未存滿的情況。這時,就無法在硬碟上建立新檔案。
每個 inode 都有一個號碼,作業系統用 inode number / inumber 來識別不同的檔案。Unix 內部不使用檔名,而是使用 inode 號碼來識別檔案。
1. 使用者通過檔名,開啟檔案
2. 系統找到這個檔名對應的 inode 號碼
3. 通過 inode 號碼,獲取 inode 資訊
4. 根據 inode 資訊找到 data block
5. 讀出資料

檔名不會被存在 metadata 內,而是會被存在父資料夾內,目錄檔案的結構是一系列目錄項(dirent)的列表。每個目錄項,由兩部分組成:所包含檔案或目錄的名字及對應的 inode 號碼。

## 時間
| Abbreviation | Name | Description |
|--------------|------|-------------|
| mtime | Modified time | 內容資料變更的時間 |
| ctime | Status time | 權限與屬性變更的時間 |
| atime | Access time | 檔案的內容被取用的時間 |
## 指令
### 改變檔案屬性與權限
#### [`chgrp`](https://linux.die.net/man/1/chgrp)
**改變檔案所屬群組**,需存在於 `/etc/group`。
```shell
$ chgrp <group> <file>
```
`-R`:recursive。
#### [`chown`](https://linux.die.net/man/1/chown)
**改變檔案擁有者和所屬群組**,使用者需存在於 `/etc/passwd`。
```shell
chown <[owner][:group]> <file>
```
#### [`chmod`](https://linux.die.net/man/1/chmod)
**改變權限**,可以使用數字或者是符號來進行權限的變更。
```shell
$ chmod <mode> <file>
$ chmod 755 file
$ chmod u=rwx,go=rx file
$ chmod a+w file # a 代表 all
$ chmod a-w file
```
### 操作目錄
#### `cd`
Change directory
* `-` 上一個工作目錄
* `~user` 到 user 的家目錄
#### `pwd`
Print working directory
* `-P` 連結檔的路徑會以實際路徑顯示
#### `mkdir`
Make directory,群組為 [effective group](https://hackmd.io/JaR3BbMfSe6FwEIdcwStuw#etcgroup)。
* `-p` 一次建立多層目錄
* `-m 731` 設定權限,權限預設參考 umask
#### `rmdir`
Remove empty directory
* `-p` 一次刪除多層空目錄
### 檢視檔案與目錄
#### `ls`
List directory contents
* `-S` 以檔案大小排序
* `-t` 以時間排序
* `-i` 列出 inode 號碼
### 操作檔案與目錄
#### `cp`
* `-r` 遞迴,用於複製目錄
* `-i` 若檔案若存在時詢問
* `-a` 等於 `-dr --preserve=all` ,將檔案的所有特性、權限、時間等都一起複製
* `-s` 複製成為 symbolic link(檔名出現 `->` )
* `-l` 複製成為 hard link

#### `rm`
* `-r` 遞迴刪除
* `-i` 刪除前詢問
#### `mv`
* `-f` 強制覆蓋
* `-i` 檔案若存在時詢問
* `-u` source 比 destination 新時覆蓋
> TODO:更改大量檔案 rename[color=#f73b47]
### 檢視檔案內容
#### `cat`
Concatenate
* `-n` 顯示行號
#### `less`
man 也是呼叫 less 顯示說明文件。
#### `head` & `tail`
顯示文件頭尾的幾行,預設為 10 行。
* `-n` 行數
* `-f` tail 可以一直**偵測檔案新增內容**,直到 Ctrl-C 結束
> TODO: -F [color=red]
## 參考資料
* [Linux 檔案與目錄管理 / 鳥哥的 Linux 私房菜](http://linux.vbird.org/linux_basic/0220filemanager.php)
* [inode / Wiki](https://zh.wikipedia.org/wiki/Inode)
* [Reading files the hard way](https://fasterthanli.me/blog/2019/reading-files-the-hard-way-3/)