---
# System prepended metadata

title: Linux FHS 和指令

---

# Linux FHS 和指令
[TOC]
## Linux FHS
- FHS 全名：Filesystem Hierarchy Standard（檔案系統階層標準）
   - 定義：定義 Linux like 系統中的檔案的目錄結構和目錄內容
    - 目的：讓系統和使用者可以有一套標準知道檔案該存放在哪個目錄
    
![image](https://hackmd.io/_uploads/HJgMMbrhT.png)


## Linux FHS架構
![image](https://hackmd.io/_uploads/r16H-hOh6.png)
|檔案顏色 |意義|
|-----|--------|
|藍色|目錄 |
|綠色|可執行檔 |
|紅色|壓縮檔|
|淺藍色|連結檔|
|白色|普通檔 |
|黃色|設備檔 |

[source](<https://madhusudhansubedi.wordpress.com/2016/07/19/linux-file-system-hierarchy-standards-fhs/>)
- /
   - root 目錄、最高層級的目錄
   - 所有目錄和檔案的起始點
   - 類似樹狀結構
    - ex : linux 用 ls 查看根目錄的架構 
- /bin
   - 可執行的二進制檔案
   - 存放常用的 linux 指令， ex : cp 、 cd 、 ls 、 cat
   
::: info
### 修改 /bin 指令
```=
    cd /bin
    sudo cp cat dog
    dog cat
```
:::
- /sbin
   - super binary ，存放管理系統的指令
   - ex : cfdisk、dhcpcd、dump、e2fsck、fdisk、halt、ifconfig
- /usr
   - 存放用戶工具和應用程式,且大部分掛載 為 read-only
::: info
###  /bin、/sbin、/usr/sbin、/usr/bin 的差別
|目錄 |目錄內放的內容|執行權限|
|-----|--------|----|
|/bin| 常用的基本指令  |  user  |
|/sbin  |系統層級的命令 | root    |
|/usr/bin|非使用者必備的二進位檔案|user
|/usr/sbin|非系統平時運作所需要的指令|root

- 為了簡化系統管理 /{bin,sbin,lib}/ 目錄合併成 /usr/{bin,sbin,lib}/

:::
- /boot
   - 存放開機要用的檔案
   - ex : GRUB 開機的設定檔、Linux 內核映像檔案
   - ![image](https://hackmd.io/_uploads/ryLtH3u2p.png)
- /dev
   - 基本的設備檔案
   - ex : 鍵盤、滑鼠、硬碟、螢幕
    - ![image](https://hackmd.io/_uploads/H10G8n_n6.png)
- /etc 
   - 系統和應用程式的設定檔案
   - 放 web server 的設定檔 : apache2、nginx、lighttpd 
   - 系統的設定
       - /etc/timezone : 時區
       - /etc/environment : 系統環境變數
    - 用戶的設定
        - /etc/passwd : user 的資料檔
        -  /etc/shadow : 實際放 user 密碼的檔( root 才能讀取)
        -  /etc/group : 群組檔
    - 網路的設定
        - /etc/hosts
        - /etc/resolv.conf : DNS Server
::: info
### /etc/passwd 和 /etc/shadow 的差別？
- /etc/passwd 任何使用者都可以查看的檔案，/etc/shadow 只有root能讀取
- /etc/passwd 為了安全不會存跟密碼相關的資訊， /etc/shadow 存雜湊後的密碼
- /etc/passwd : 
![螢幕擷取畫面 2024-02-29 114613](https://hackmd.io/_uploads/HysDCOp26.png)
    - 1 : 使用者名稱
    - 2 : 密碼
    - 3 : UID
    - 4 : GID
    - 5 : 使用者資訊說明欄
    - 6 : 家目錄
    - 7 : Shell (跟系統溝通的介面)
- /etc/shadow : 
![image](https://hackmd.io/_uploads/S1ikJYThp.png)
    - 1 : 使用者名稱
    - 2 : 密碼(雜湊後的)
    - 3 : 最近更動密碼的日期
    - 4 : 密碼不可被更動的天數
    - 5 : 密碼需要重新變更的天數
    - 6 : 密碼需要變更期限前的警告期限(7 天內系統會警告帳號)
    - 7 : 密碼過期的恕限時間(當密碼失效後，n 天內還可以登入)
    - 8 : 帳號失效日期
    - 9 : 保留(欄位是保留的，看以後有沒有新功能加入)
:::

- /media 
   - 用於臨時掛載可移除設備的目錄
   - ex :插入 USB 後，系統會將其掛載到 /media 目錄下供使用。
- /mnt
   - 管理員、使用者放置臨時手動掛載的目錄
   - /media 自動掛載，/mnt 手動掛載
::: info
### 甚麼是掛載？
- 把設備連接到一個存在的目錄上
- 掛載指令: mount [-t type] device dir
    - type：文件系統的類型，例如 : ext3、ext4、NTFS、VFAT 
    - device：要掛載的裝置文件，例如 : /dev/sda1、/dev/sdc
    - dir：掛載點，例如 : /mnt/mydisk 
    - 例如 : sudo mount -t ntfs /dev/sda1 /mnt/mydisk
- 解除掛載指令: umount dir
    - 例如 : sudo umount /mnt/mydisk 
:::
- /opt
   - 存放安裝的第三方應用程式
   - ex : 放下載好的 chrome
- /tmp
   - 存放系統或使用者產生的暫存檔案
   - 任何使用者都能存取
   ![image](https://hackmd.io/_uploads/r1D9rYaha.png)
   > 系統會在某些時刻清除目錄下的檔案  
   > 建議檔案不要存這
- /lib
   - 存放系統和應用程式所需的函式庫檔案
       - 執行 /bin 、 /sbin 目錄所需要的函式庫
   - /lib32 和 /lib64
       - 分別為32和64位元函式庫
- /run
    - 暫存程式或服務需要的檔案
- /proc
   - 儲存的是當前核心運行狀態
- /home
    - 系統預設的家目錄，存放在系統上的所有使用者的目錄(不包含 root )
    - 新增的使用者
        - adduser : 會產生屬於這使用者的家目錄
        - useradd : 只會單純產生使用者，但不會產生家目錄
    - ~
        - cd ~ : 回到自己的家目錄
        - cd ~<使用者> : 去其他使用者的家目錄
- /srv
   - 存放與服務相關的資料和檔案
   - ex : web server 產生的 data
   - ex : /srv/ftp ，存放 ftp 的服務產生的資料
- /var
   - 存放系統產生的變動資料
   - /var/cache : 應用程式產生的緩存檔
   - /var/spool：這個目錄用於存放等待處理的任務，如影印和郵件
   - /var/tmp：這個目錄用於存放需要在重啟後仍然存在的臨時文件
   - /var/lib : 放應用程式的資料
       - database 的表格
   - /var/mail : 存放使用者的信件
    - /var/lock : 放應用程式共用的檔案，避免多個程式同時存取
    - /var/log : 系統日誌
        -  boot.log : 紀錄開機或一些服務啟動的檔
        -  wtmp : 記錄登入者資料
        -  faillog : 紀錄登入失敗訊息
        -  kern.log : kernel 產生的紀錄
    
## 指令補充
### 基本指令
- cd : 切換目錄
    - `.` : 現在這層目錄
    - `..` : 上一層目錄
    - `-`: 前一個工作目錄
    - ``~` : 這個 user 的家目錄, cd 也可以直接回家目錄
    - `~<username>` : 指定 user 的家目錄
- pwd : 取得目前的路徑
- history : 查看使用過的指令紀錄
 - ls : 列出目錄下的檔案
      - -l : 顯示檔案詳細訊息
      - -a : 顯示所有檔案(隱藏檔案) 
      - -F : 用符號顯示檔案類型
      - -h : 依字母排序列出檔案
      - -r : 依字母反向排序列出檔案
      - -t : 依照檔案修改時間列出
      - -s : 依照檔案大小排序
      - -R : 遞迴列出目錄下所有檔案
    >隱藏檔案 : 檔名以.開頭的檔案

### 檔案、目錄相關
#### 各欄位意義
-   檔案類型
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/SyzWMIhh6.png)
    - `-` : 代表普通的檔案
    - `d` : 代表目錄
    - `l` : 代表連結
    - `p` : 有用 `|` (pipe) 的檔案
    - `b` : 存取硬體設備的檔案 (暫存再寫入)
    - `c` : 存取硬體設備的檔案 (立即)
     - `s` : socket 檔案
    
- 權限
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/S1VFfI2n6.png)
    - 共三組 rwx 分別代表三個角色，擁有者、所屬群組、其他人
    - r : Read
    - w : Write
    - x : eXecute
- 底下有幾個目錄 / Hard Link 數量
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/HJiE78hnp.png)
- 擁有者
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/ryaDQ8nnp.png)
- 群組 
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/S1KY7U336.png)
- 檔案大小
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/Bk7jm8h3a.png)
- 最後修改時間
![upload_8feb44642e3826b250dbd9e70cc47565](https://hackmd.io/_uploads/HJyRX8h3p.png)

- touch <filename.filetpye> : 建立空檔案
- mkdir <directory name> : 建立目錄
- mv : 移動或重新命名檔案
    - mv <原始位置> <目標位置> : 將檔案或目錄移動到另一個位置
    - mv <原檔名> <新檔名> : 將檔案或目錄重新命名
    - mv <file1> <file2> ... <目錄> : 將多個檔案移動到另一個目錄
    - mv -r <目錄1> <目錄2> : 用遞迴把目錄1下的所有檔案移到目錄2
- cp : 複製檔案
    - cp <file> <copy_file>
    - cp <directory> <copy_dir>
    - 加參數
        - -a : 複製檔案全部特性
        - -p : 連同檔案的權限、owner、時間一起複製
        - -r : 遞迴複製目錄下的所有檔案 
- rmdir : 刪除指定的空目錄
- rm : 刪除檔案或目錄
    - rm <file> : 刪除檔案
    - rm -r <目錄> : 刪除目錄下所有的檔案，並刪除目錄
    - rm -f <file> : 強制刪除檔案
    - rm -i <file> : 刪除前確認時否刪除
    - rm <目錄>/* : 清空目錄下的檔案(不包含目錄)
- echo <content> : 輸出使用者輸入的內容
    -    echo <content> > <filename> : 建立一個檔案並把內容寫入，如果檔案已經存在會清空內容再寫入
    -  echo <content> >> <filename> : 建立一個檔案並把內容寫入，如果檔案已經存在會寫入在檔案的最後一行
    - echo * : 顯示目前目錄下的所有檔案
    - echo $(指令) : 用echo執行指令
    - echo {1..5} : 輸出串列
- cat : 輸出指定檔案的內容
    -    cat <file>
    - cat <file1> <file2> : 印出多個檔案內容
    - cat <file1> <file2> > file3 : 多個檔案內容寫入到其他檔案並覆蓋
    - cat <file1> <file2> >> file3 : 多個檔案內容寫入到其他檔案的最後一行
    - 加參數
        -    -b : 印出行號，空白行不標記
        - -n : 印出行號，空白行也標記行號
        -    -T : 會把 TAB 按鍵用 ^I 顯示出來
- grep : 找關鍵字
    - grep <keyword> : 從輸出中找指定的關鍵字    
    - grep <keyword> <file> : 找出檔案是否有這個關鍵字
    - 加參數
        - -i : 列出所有不論關鍵字大、小寫的結果
        - -n : 印出行號
        - -E : 用正規表示法顯示輸出
            - ls | grep -E D.*o : 用`|`把 `ls` 的輸出傳給 `grep` 並 `-E` 以正規化的方式輸出第一個字為 `D` 下一個字為 `o` 的關鍵字
::: info
### 管線命令（pipe）
- 允許將一個命令的輸出作為另一個命令的輸入
- 管線命令使用`|`符號實現，將多個命令串在一起，形成一個pipeline
- [command1]`|`[command2]`|`[command3]`|`... 
- command2 會處理 cmmand1 的輸出，command3 會處理 cmmand3 的輸出，以此類推
- 例如 :
    - `ls -l / | less` : 把 `ls -l` 的輸出交給 `less` 處理，就可以用翻頁的方式查看根目錄下的檔案
    - `ls -l /var/log | grep -E *.log` : 根據 `ls -l`的輸出找 `log` 這個關鍵字
    
:::  
- ln <source_file> <link_file> : 建立一個指到目標的連結
    - ln <file1> <file2> : Hard Link，file1 和 file2 進行連結，file2 以 file1 為主 ，任一個檔案有變動，連結的檔案也會跟著變
    - ln -s <file1> <file2> : Soft Link (Symbolic link)，file1 和 file2 進行連結，類似 windows 上的捷徑
::: info
###  Hard link 和 Soft link 的差別
|差異 |Hard link|Soft link|
|-----|--------|----|
|連結類型| 它是一種指向同一個 inode 的多個名稱  |它是一個指向原始文件的捷徑  |
|檔案連結類型  |只能用於文件，不能用於目錄 | 可以用於文件和目錄    |
|更新|所有連結文件都會更新|所有連結文件都會更新
|刪除|當連結數為1，才會真正刪除文件|刪除連結的檔案不會影響原始檔案
- `inode` : 用於唯一識別系統中的文件和目錄
    - `ls -i` : 查看檔案的 inode 編號
:::

### 使用者相關
- whoami : 我是誰，哪個使用者
- groups : 顯示出目前的使用者的所屬群組
- id : 查看自己的 UID ，所屬群組的 GID
    - sudo id <username> : root 查閱其他使用者 UID ， GID
    - id 可以用來唯一識別使用者
    - 0 是 root 1~500 是系統保留的 ID ， 500~65535 是一般使用者，        依序遞增
- who : 當前使用者登入紀錄 
- last : 當前和最近使用者登入的紀錄
- sudo : 使用 root 的權限
- su <username> : 輸入密碼，更換使用者，建議用 sudo su <username>
- exit : 登出現在的使用者是 ctrl+D
- usermod : 修改使用者資訊
    -   sudo usermod -l <new_name> <old_name> ： 修改帳號名稱
    -    sudo usermod -s <shell dir> <username> ：修改使用者的家目錄
- adduser : 新增使用者
- passwd : 更改使用者的密碼
    - sudo passwd <username> : 強制更改其他使用者的密碼
- sudo groupadd <group_name> : 新增群組
    - -g <id> : 自訂 group 的 id
- sudo groupdel <group_name> : 刪除群組
- groupmod : 修改與 group 相關資訊
    - gpasswd <groupname> : 設定群組密碼
    - -A <username> : 新增 user 成為群組管理員
    - -r : 刪除該群組的密碼
    - -R : 讓該群組的密碼欄失效
    - 群組管理員可執行的指令
        - gpasswd -a <username> <group_name> : 將指定 user 新增至群組
        - gpasswd -d <username> <group_name>: 將指定 user 從群組移除
### 與權限相關

- chmod : 改變檔案讀取、寫入、執行的權限
    - a : 代表所有人
    - u : 代表使用者
    - g : 代表群組
    - o : 代表其他人
    - `+` : 可以
    - `-` : 不可以
    - chmod a+r filename : 所有人可以讀取
    - chmod a+rw filename : 所有人可以讀寫
    - chmod o-rwx filename : 其他人不可以讀寫和執行
    - chmod og-r filename : 其他人和群組不可以讀取
::: info
### 權限管理
- `r` : 判斷是否能讀，用4代表
- `w` : 判斷是否能寫，用2代表
- `x` : 判斷是否能執行，用1代表
    - chmod 755 <filename/dir_name> : owner 可讀可寫可執行，其他使用者可讀可執行
![image](https://hackmd.io/_uploads/SkAV_ss2a.png)
:::

- chgrp : change group, 改變所屬群組
    - chgrp <group> <filename>
    - chgrp [-r] <group name> <dirname/filename> 
        - recursive, 進行遞迴的持續變更，常用在目錄變動的參數   
    - /etc/group 中記錄現有的群組，群組名稱要在檔案裡才可以執行 chgrp 指令
- chown : change owner ，改變檔案或目錄擁有者
    - chown <owner> <file>
    
### 與查詢相關

- man <指令>, <指令> -h, <指令> --help : 查指令使用方式
- less : 查看檔案的內容，可以自己翻頁
    > cat : 是輸出所有內容
- head : 輸出檔案前面幾行的內容
- tail : 輸出檔案最後幾行的內容
- file : 用於判斷檔案類型    
- whereis <command> : 從一些特定的目錄中尋找檔案的檔名
    - -l : 可以列出 whereis 會去查詢的幾個主要目錄而已
    - -b : 只找 binary 格式的檔案
    - -m : 只找在說明檔 manual 路徑下的檔案
    - -s : 只找 source 來源檔案
- which <command> : 查找指令存的位置
    - -a : 將所有找到的指令列出
- find [要查的目錄] <條件> : 根據設定的條件查詢檔案或目錄 
    - find /etc -iname 'network' : 查詢 etc 目錄下的檔案名為 network
    - find /var/log -iname '*.log' -type f : 查詢 /var/log 目錄下的副檔案名為 log 的檔案
    - find /etc -iname 'apache2' -type d : 查詢 /etc 目錄下為 apache2 的目錄
- env : environment，顯示目前 shell 下的所有環境變數與說明 
- printenv : 輸出所有的環境變數 
- type <command> : 查看指令類型，例如區分是shell的內部還外部指令
    - -t : 輸出出指令的類型
         - file ：表示為外部指令
         - alias ：表示該指令為命令別名所設定的名稱
         - builtin ：表示該指令為 bash 內建的指令
    
### 與下載相關
  - apt install <package_name> : 安裝套件
- apt remove <package_name> : 刪除套件
- apt upgrade <package_name> : 更新套件
- wget <網址> : 從指定網址安裝，會放在 /opt 
- dpkg -i <filename.deb> : 用 deb 檔型安裝，會放在 /opt
    - i : install
    -  r : remove
    - l : list

### 與網路相關
- ifconfig
    - 安裝: sudo apt install net-tools
    - 執行: ifconfig
    ![image](https://hackmd.io/_uploads/SJDeWH3hp.png)
    - sudo ifconfig <網卡名稱> down : 關閉網卡
    - sudo ifconfig <網卡名稱> up : 開啟網卡
    - ifconfig -a : 查看所有網卡
- route : 查看 host 的 routing table
    - -n : 會把能變成數字的資訊變成數字，主機名稱以 IP 顯示
- ping <網址> : 查看網路連線狀態 
    ![image](https://hackmd.io/_uploads/ByAy7rhhp.png)
- nslookup : 查詢 DNS server
- netstat : 可以看到目前電腦網路的詳細狀況
    - -a : 列出所有連結的 port
    - -p : 顯示伺服器 process ID / 名稱
    - -at : 只列出 TCP
    - -au : 只列出 UDP
    - -l : 列出所有 listening 狀態的 port
    - -lt : 列出所有 listening 狀態的 TCP port
    - -lu : 列出所有 listening 狀態的 UDP port
    - -s : 列出個協定的統計資料
    - -r : routing table
    - 例如 : 
        - netstat -tunlp : 顯示 TCP 和 UDP 的連接狀態 
        - netstat -an :　顯示所有開啟的 socket
        - netstat -rn : 顯示所有路由表，等於 route -n
- ip :　網路參數綜合指令
    - ip [option] [動作] [指令]
        - option : 設定的參數
            - -s : 顯示出該裝置的統計數據(statistics)
    - 動作 : 針對哪些網路參數進行動作
        - link :　關於裝置 (device) 的相關設定，包括 MTU, MAC 位址等等
        - addr/address ：關於額外的 IP 協定
        - route ：與路由有關的相關設定
    - 指令
        - show : 僅顯示出這個裝置的相關內容
    - ip link set [device] [動作與參數]
        - set : 可以開始設定項目， device 指的是 eth0, eth1 等等網卡代號
        - 動作與參數
            -  up/down : 啟動 (up) 或關閉 (down)
            -   address : 如果這個裝置可以更改 MAC 的話
            -  name : 給予這個裝置一個特殊的名字
            -  mtu : 封包傳輸的最大單位量( byte ) 
    - 例如 : 
        - ip link show : 顯示所有網卡的資訊
        - ip -s link show eth0 : 顯示所有網卡的統計數據
        - ip link set enp0s3 up : 開啟 enp0s3 網卡
        - ip link set enp0s3 down : 關閉 enp0s3 網卡
        - ip link set enp0s3 mtu 1000 : 設 enp0s3 網卡最大傳輸的封包量為 1000 byte
        - ip address show : 顯示出所有的介面之 IP 參數
- ss : Socket Statistics ，顯示 sockets 的統計數據, 跟 netstat 指令類似, 但因從 kernel 讀取數據, 所以速度較快 
    - -l : 顯示監聽狀態 port
    - -pl : 列出開啟 Socket 的 process 名稱
    - -a : 列出所有資訊
    - -t : 只列出 TCP Sockets
    - -u : 只列出 UDP Sockets
    - -x : 只列出 Unix Sockets
    - -4 : 只列出 IPv4 Sockets
    - -6 : 只列出 IPv6 Sockets
### process 相關的指令
- top : 即時更新，顯示當前運行的 process
- ps : 顯示當前運行的 process
    - -a : 不與 terminal 有關的所有 process
    - -A : 有的 process 都列出，與 -e 具有同樣的效用
    - -x : 與 terminal 有關的所有 process
    - -axu
    ![image](https://hackmd.io/_uploads/SJ-uy8nn6.png)
        - USER : process 擁有者
        - PID : process 的唯一識別碼
        - %CPU : 佔用 CPU 的使用率
        - %MEM : 佔用實體記憶體的比例
        - VSZ : 佔用的虛擬記憶體大小
        - RSS : 佔用的記憶體大小
        - STAT : process 的狀態
        - TIME : process 的執行時間
 - kill <pid> : 根據 process id 終止 process
     - ex : kill firefox process
         - ps axu | grep firefox : 找 firefox 的 process
        - kill <找到的 pid >

