---
# System prepended metadata

title: shell 命令 - 裝置資訊、處理數據
tags: [Linux Shell]

---

---
title: 'shell 命令 - 裝置資訊、處理數據'
disqus: kyleAlien
---

shell 命令 - 裝置資訊、處理數據
===

## OverView of Content

這章演示如何透過指令來探查 Linux 裝置訊息

[TOC]

## 追蹤程序

追蹤程序通常有兩個命令 `stace`（系統呼叫追蹤）、`ltrace`（系統函式庫追蹤）

### 追蹤系統呼叫 - strace

* **`strace` 命令**：可以 **追蹤程序 `fork` 後的所有涉及系統呼叫的行為**；範例如下

    ```shell=
    strace cat /dev/null
    ```
    簡單分析以下系統呼叫
    
    1. 使用 `execve` 命令去覆蓋 fork 命令後的記憶體區塊，去執行新的命令… 並使用 `brk` 來初始化記憶體

        ```shell=
        execve("/usr/bin/cat", ["cat", "/dev/null"], 0x7fc339ef08 /* 50 vars */) = 0
        brk(NULL) 
        ```
        
    2. 共享函式庫的載入，載入多個 so 庫（`ld.so.preload`、`ld.so.cache`、`libc.so.6`、``）

        ```shell=
        faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
        openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
        fstat(3, {st_mode=S_IFREG|0644, st_size=79836, ...}) = 0
        mmap(NULL, 79836, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f81b1e000
        close(3)                                = 0
        openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
        read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0`\17\2\0\0\0\0\0"..., 832) = 832
        fstat(3, {st_mode=S_IFREG|0755, st_size=1455120, ...}) = 0
        ```
    
    3. 開啟 `/dev/null` 裝置，如果核心開啟檔案成功，則會返回 3

        ```shell=
        openat(AT_FDCWD, "/dev/null", O_RDONLY) = 3
        ```
        
        :::warning
        * 如果核心開啟檔案失敗，則會返回 -1

            ```shell=
            openat(AT_FDCWD, "/dev/hello", O_RDONLY) = -1 ENOENT (No such file or directory)
            ```
        :::
    
    4. 退出

        ```shell=
        close(3)                                = 0
        close(1)                                = 0
        close(2)                                = 0
        exit_group(0)                           = ?
        +++ exited with 0 +++
        ```
    
    > ![](https://hackmd.io/_uploads/S1-CxXg52.png)


### 追蹤系統函式庫 - ltrace

* **`ltrace` 命令**：它不追蹤核心即別的內容，只追蹤共享函式庫 

    ```shell=
    ltrace cat /dev/null
    ```

## 監看 Process、Thread

Process 就是一個應用的最小單位，每個應用都會有自己專屬的 Process ID


### 查看 Process 訊息 - ps

* 基礎使用如下；而 `ps` 這個命令有許多的參數，這邊這會列出幾個常用的參數，其餘的參數可以使用 `man ps` 去查詢

    ```shell=
    ## 查看當前用戶所使用的進程資訊

    ps
    ```
    > ![](https://i.imgur.com/201Sq31.png)
    
    Linux 系統中的 GNU **ps 命令支持 3 種不同類型參數**
    
    1. **Unix 風格**：單破折線 (`-<options>`)，以下是常用參數

        | 參數 | 功能 |
        | - | - |
        | **-A / -e** | 顯示所有的進程（不限用戶） |
        | **-f** | 顯示完整格式輸出 |
        | **-l** | 長列表 |
        | -N | 顯示與指定參數不同的進程 |
        | -a | 顯示除了 控制進程 (session leader) 和 無終端進程之外的所有進程 |
        | -d | 顯示除了 控制進程 (session leader) 之外的所有進程 |
        | -C <cmdlist\> | 顯示指定列表中的進程 |
        | -G <grplist\> | 顯示列表中指定的 GID 進程 |
        | -U <userlist\> | 顯示列表中指定的 UID 進程 |


        ```shell=
        ## Unix 風格常用組合

        ps -ef
        
        ## 下表說明 -efl 輸出的欄位說明
        ps -efl
        ```
        > ![](https://i.imgur.com/M81GS0p.png)
        
        | 輸出欄位（前到後） | 說明 | 補充 |
        | - | - | - |
        | F | 內核分配給系統的標記 |  |
        | S | 進程當前狀態 | Ｏ：運行、Ｓ：睡眠、Ｚ：僵化、Ｒ：等待中彈可運行、Ｔ：停止 |
        | UID | 啟動該進程的的用戶 |  |
        | PID | 進程編號 |  |
        | PPID | 父進程編號 |  |
        | C | 進程的 CPU 使用率 |  |
        | PRI | 優先級 | 數字越大越優先 |
        | NI | 謙讓度 | 與 PRI 共同決定最終的優先級 |
        | ADDR | 進程的內存地址 |  |
        | SZ | 若進程被換出，所需要的交換空間大小 | Swap size |
        | WCHAN | 進程休眠時的內存地址 |  |
        | TTY | 進程啟動的終端設備 |  |
        | TIME |  進程使用 CPU 的累積時間 | 格式：`hh:mm:ss` |
        | CMD | 啟動的程序名稱 | 可能會更改 |


    2. **BSD 風格**：無破折線（`<options>`）；以下說明幾個常見的 options
        
        :::info
        BSD 風格的 ps 命令相對簡單
        :::
        
        | 參數 | 功能 |
        | - | - |
        | T | 跟蹤與當前終端有關的進程 |
        | a | 所有終端的進程 |
        | g | 顯示所有終端的進程（包括控制進程） |
        | r | 僅顯示運行中的進程 |
        | **x** | 顯示所有進程，包括未分配終端的進程 |
        | l | 長模式 |
        | s | 信號格式顯示 |
        | **u** | 基於用戶的格式顯示 |
        | v | 採用虛擬內存的方式顯示 |
        | **w** | 顯示命令全名，而非簡易名稱 |

        ```shell=
        ## BSD 風格常用組合
        ps s
        
        ps xl
        
        ps aux
        ```

        :::info
        加州伯克利分校開發的 Unix 版本，大部分與 Unix 風格可獲得的數據相差不大，它的特點是，它可以 **獲得更詳細的進程資訊** （如下表）
        :::
        
        | BSD 特色欄位 | 說明 | 補充 |
        | - | - | - |
        | VSZ | 進程在內存中的大小 | 大小為 KB |
        | RSS | 物理內存的大小 |  |
        | STAT | 當前進程的狀態 | `<`：進程運行在高優先級上、`N`：進程運行在低優先級、`L`：進程有頁面鎖定在內存、`s`：控制進程、`l`：多線程進程、`+`：運行在前台、`S`：可休眠的進程 |

        
        > ![](https://i.imgur.com/B7bBmoe.png)

        :::success
        * ps + `$$` 參數配合：可以獲得屬於當前程序的運行程序
            
            ```shell=
            ps u$$
            ```
        
            > ![](https://hackmd.io/_uploads/HkHDRd_Ln.png)
        :::

        
    3. **GNU 風格**：雙破折線（`--<options>`）；改進 ps 命令中加入了另外一些參數；

        ```shell=
        ## 查看進程之間的關係 (最後的 COMMAND 會有父子關係圖)

        ps aux --forest
        ```
        > ![](https://i.imgur.com/A6LdSvX.png)


### 查看 Thread

* 透過 ps 命令選項 `m`，可以查看到用戶下的程序都使用哪些進程

    ```shell=
    ps am
    ```

    > 下圖，PID 下的 `- -` 代表該進程下有幾個 Thread()
    > 
    > ![](https://hackmd.io/_uploads/HyoOdmx92.png)


### 實時監測 Process - top

* 當你下達 `ps` 命令時你所獲取的是當下的進程資訊，當有進程更新時（或有進程關閉、開啟）是不會實時更新的

* 使用 `top` 命令就可以實時監測進程

    ```shell=
    top
    ```
    > ![](https://i.imgur.com/kPkxPX0.png)

    1. 第一行：當前時間、系統運行時間、登入用戶數量、平均負載（1min 5min 15min）
        
        :::info
        * 平均負載 15 分鐘仍在 2 以上說明系統在繁忙狀態
        
        * 可以使用 `uptime` 命令來查看 相同效果
            
            > ![](https://hackmd.io/_uploads/SyQk27e53.png)
        :::
        
        > ![](https://i.imgur.com/RoURFR7.png)

    2. 第二行：系統中進程的總數、狀態

        :::info
        * `top` 命令中將進程稱為 `task`
        :::
        
        > ![](https://i.imgur.com/stUoRyw.png)

    3. 第三行之後：
        
        * CPU 訊息，根據進程的 owner & 進程的狀態將 CPU 利用率分成幾類輸出

        * 記憶體分配、使用、剩餘
        
        * 交換記憶體的訊息 （物理空間當記憶體的狀態）

            > ![](https://i.imgur.com/NjHiGX5.png)

    4. 內容欄位：

        | 欄位 | 說明 |
        | - | - |
        | PID | 進程 ID |
        | USER | 進程的 Owner |
        | PR | 進程優先級 |
        | NI | 進程謙讓度 |
        | VIRT | 進程所佔用的虛擬記憶體量 |
        | RES | 物理內存的總量 |
        | SHR | 與其他進程共享的內存總量 |
        | S | 進程狀態（Ｄ：可中斷、Ｒ：運行中、Ｓ睡眠、Ｔ：跟蹤或停止、Ｚ：僵化） |
        | %CPU | 進程使用的 CPU 時間百分比 |
        | %MEM | 進程佔用的內存百分比 |
        | TIME+ | 進程啟動到目前為止使用了多少 CPU 時間 |
        | COMMAND | 進程名 |

* `top` 命令是一個互動式進程，可以透過以下字符來改變 `top` 設定

    | 鍵入字符 | 功能 |
    | - | - |
    | `d` | 設定 `top` 更新時間 |
    | `f` | 改變 `top` 的顯示順序（預設 %CPU 排序）、顯示內容 |
    | `q` | 退出 |

    > `f` 的設定頁面
    > 
    > ![](https://i.imgur.com/ViRpom2.png)

    > 改變顯示順序為 `%MEM` 排序
    > 
    > ![](https://i.imgur.com/C6sPN3j.png)

### 結束進程 - kill / killall


* Unix 進程之間的通訊其中一個辦法就是 **通過 ==信號== 通訊**，Linux 也沿用這個方法；其信號與意義如下表

    | 信號 | 名稱 | 意義 |
    | - | - | - |
    | 1 | HUP | 掛起 |
    | 2 | INT | 中斷 |
    | 3 | QUIT | 結束運行 |
    | 9 | KILL | 無條中終止 |
    | 11 | SEGV | 段錯誤 |
    | 15（Kill 默認） | TERM | 盡可能地終止（如果不能終止也不能怎麼辦） |
    | 17 | STOP | 無條件停止運行（不等於終止） |
    | 18 | TSTP | 停止或是暫停，再次啟動後繼續在後台運行 |
    | 19 | CONT | 在 STOP、TSTP 之後恢復運行 |

* `kill` 命令：可以對指定進程傳入不同信號

    ```shell=
    # 對 PID 為 1234 的進程下達強致終止的信號

    kill -s 9 1234
    ```

* `killall` 命令：透過進程名（`Command` 欄位）來關閉進程

    ```shell=
    ## 關閉 http 開頭相關進程

    killall http*
    ```
    :::warning
    要小心使用這個命令，否則可能會導致文件系統損壞
    :::

<!-- 
## CPU、記憶體、IO 監控


### 測量 CPU 時間

* 除了使用 `top` 命令監控系統之外 -->


    
## 監看磁碟、檔案

在Linux系統上有幾個命令行命令可以用來幫助管理存儲媒體

### lsof - 開啟的檔案

* **`lsof` 命令**：`list open files` 會列出 **打開的檔案**、**使用它們的程序**，甚至包括 **網路資源、動態函數、管道**

    ```shell=
    lsof | head
    ```
    
    其中欄位意義如下
    
    | 欄位 | 說明 |
    | - | - |
    | `COMMAND` | 描述擁有該檔案描述符的程序名稱 |
    | `PID` | 檔案的進程 ID |
    | `TID` | 檔案的線程 ID |
    | `TASKCMD` | 任務名，通常跟 `COMMAND` 相同 |
    | `USER` | 該進程所屬的 User name |
    | `FD` | **包含兩種意義**；^1.^ 表明檔案的作用（像是 `cwd`）、^2.^ 檔案的描述符（一串數字） |
    | `TYPE` | 檔案類型（像是目錄、socket... 等等） |

    > ![](https://hackmd.io/_uploads/HJhHtzlcn.png)

    1. **查看當前進程的所開啟的所有檔案**
    
        ```shell=
        # `$$` 是當前進程 ID
        
        ls -p $$
        ```
        
        > ![](https://hackmd.io/_uploads/SkO1Tzg92.png)
    
    2. **顯示 `/home/alien` 目錄中所有被開啟的檔案**
    
        ```shell=
        ps /home/alien
        ```

        > ![](https://hackmd.io/_uploads/Bkpnpzlqh.png)

### 掛載設備 - mount

* 我們知道 Linux 是使用一個虛擬目錄來管理所有的硬碟，當使用新的硬碟時，就 **必須掛載 (mounting) 硬碟到虛擬目錄之下**

    > 大部分狀況下移動式裝置都會自動掛載

* 單純使用 `mount` 命令可以查詢當前系統上已掛載的裝置；`mount` 輸出的格式代表意義如下表

    ```shell=
    mount
    
    ## 輸出格式 
    ## <設備文件> on <虛擬目錄掛載點> type (<訪問狀態>)
    ```

    > `/dev/mmcblk0p2 on / type ext4 (rw,noatime)`
    > 
    | 輸出 | 說明 | 補充 |
    | - | - | - |
    | `/dev/mmcblk0p2` | 媒體的設備文件 | - |
    | `/` | 媒體掛載到虛擬目錄的掛載點 | - |
    | `ext4` | 文件系統類型 | eg. `vfat`, `ntfs`, `iso9660` |
    | `rw` | 已掛載的媒體訪問狀態 | `ro` 只能讀、`rw` 可寫可讀、`user` 普通用戶掛載文件系統、`loop` 掛載 **文件** | 

    > ![](https://i.imgur.com/wJpGENA.png)

* 掛載：手動掛載設備

    ```shell=
    ## 格式：mount -t <type> <device> <directory>

    ## 掛載檔案類型 ext4
    ## 裝置在 /dev/test_device
    ## 掛載到虛擬目錄的 /mnt/my_device 資料夾中
    sudo mount -t ext4 /dev/test_device /mnt/my_device
    ```

* **卸載**：移除已掛載設備 （如果設備 busy 就不能卸載）

    ```shell=
    ## umount [device]

    ## 卸載虛擬目錄對應的 /dev/test_device 裝置
    sudo umount /dev/test_device
    ```
    :::danger
    * 設備 busy，可以使用 `lsof` 查看使用設備的進程，並將它停止
    :::


### 文件系統空間 - df 

* df (`report filesytem disk`) 命令：該命令可以透過檔案系統獲取當前硬體已經使用的空間

    > 以檔案系統的角度去查看容量，一個硬碟中可能有多個分區，也就是會存在多個檔案系統，所以 `df` 並不代表硬碟總空間）

    ```shell=
    df
    
    ## 輸出
    ## /dev/root      246108604 7232432 228818000   4% /
    ```
    | df 欄位 | 輸出數值 | 說明 |
    | - | - | - |
    | FileSystem | /dev/root  | 設備（device）位置 |
    | 1K-blocks | 246108604 | 總容量（1K 為單位） |
    | Used | 7232432 | 已使用（1K 為單位） |
    | Available | 228818000 | 還可以使用（1K 為單位） |
    | Use% | 4% | 已使用的百分比 |
    | Mounted on | / | 設備（device）掛載到虛擬目錄的位置 |

    :::info
    * df 命令注意點

        * 輸出顯示是 Linux 系統認為的當前值，並非實時值（尚未釋放的文件不會算數）
        
        * 隱藏的預留區域也會算在百分比內（所以怎麼家都不會是 `100%`） 
    :::
    
    > ![](https://i.imgur.com/skvy7xm.png)

### 硬體使用空間 - du

* du (`estimate file space usage`) 命令：該命令可以判斷 **特定目錄** 的磁碟使用空間 (與 `df` 的差異是可以指定目錄)

    > du 默認目錄為當前目錄

    ```shell=
    ## 由於輸出過長，這邊使用 head 限制輸出
    du | head
    
    ## 輸出更容易讀的單位
    du -h | head       
    ```
    
    > 輸出：4 ./Pictures

    | du 左到右輸出數值 | 說明 |
    | - | - |
    | `4.0K` | 佔用的磁碟塊（單位預設為 1K） |
    | `./Pictures` | 目錄 |

    > ![](https://i.imgur.com/l0YGgvY.png)

    `du` 其餘的 options
    
    | options | 說明 |
    | - | - |
    | `-h` | 更方便檢視大小的格式 |
    | `-c` | 已列出的文件總大小 |
    | `-s` | 顯示每個輸出參數的總計（按資料夾） |


    ```shell=
    ## 查看當前目錄中的所有資料

    du -sh *
    ```
    > ![](https://i.imgur.com/3ybamts.png)

## 處理數據


### 排序 - sort

* sort 默認會按照默認語言的的排序規則對文本中的數據進行排序

    ```shell=
    ## 查看原先數據
    cat test_Context
    
    ## sort 會按照字元（ASCII）順序排序
    sort test_Context        
    ```

    > ![](https://i.imgur.com/CW9E7wF.png)


* 以下幾個 sort 常用的 options

    | sort's options | 說明 | 其他 |
    | - | - | - |
    | -n | 將文本內容的排序改成透過數字順序排序 | - |
    | -M | 按照月份排序 | Linux 日誌文件經常會再每行的起始位，會有一個時間戳 |
    | -k POS1[, POS2]| 指定排序範圍；排序從某個位置（POS1） 到（POS2） | POS2 不指定則代表到尾 |
    | -t | 按照某個值（由你設定），將文本區分 | - |
    | -r | reverse 排序 |  |

    1. 按照月份排序內容
        ```shell=
        ## 查看原先數據
        cat test_Context

        ## 將內容按照月份排序
        sort -M test_Context2
        ```

        > ![](https://i.imgur.com/wMvgY2P.png)

    2. 按照用戶 ID 排序 `/etc/passwd`
    
        ```shell=
        ## -t 指定 ':' 區分 -> [root] [x] [0] [0] [root] [/root] [bin/bash]
        ## -k 3 排序範圍從 區分的第三個範圍開始到最後
        ## -n 用數字排序
        sort -t ':' -k 3 -n /etc/passwd
        ```
        > ![](https://i.imgur.com/vbjBFAC.png)

    3. 按照大到小排序輸出內容

        ```shell=
        ## 排序 du -sh 的輸出（大到小）

        du -sh * | sort -nr
        ```
        > ![](https://i.imgur.com/upRT0nb.png)

### 過濾數據 - grep

* `grep` 命令可以在數據海中找到你所需要的某些特定資料，格式如下 

    > grep [options] pattern [file]

    ```shell=
    ## 找尋 /etc/passwd 文件中，有 root 字的內容
    grep root /etc/passwd
    ```
    > ![](https://i.imgur.com/IegEBQC.png)


* 以下幾個 grep 常用的 options

    | grep's options | 說明 | 其他 |
    | - | - | - |
    | -v | 反向搜尋 | 顯示所有非 pattern 的內容 |
    | -n | 添加行號 | - |
    | -c | 查看符合 pattern 匹配數量 | - |
    | -e | 多匹配模式 | 可設定多個條件 |
    | -E | 正則表達式匹配 | `[]` 中括號內任意字串匹配，`''` 指定全符合才匹配 |

    1. 查詢 `/etc/passwd` 內所有沒有 root 的內容
        ```shell=
        grep -vn root /etc/passwd
        ```

        > ![](https://i.imgur.com/6nsPC2x.png)


    2. 同上，不過這邊輸出所有符合條件的數量

        ```shell=
        grep -vc root /etc/passwd
        ```

        > ![reference link](https://i.imgur.com/u3w15Zm.png)

    3. 多匹配模式，找尋 alien 或 root 關鍵字並輸出行數

        ```shell=
        grep -e alien -e root -n /etc/passwd
        ```
        > ![](https://i.imgur.com/0KTUaFJ.png)

        :::success
        
        * 當然我們也可以使用正則表達式的方式去搜尋內容

            ```shell=
            grep -E 'root|alien' -n /etc/passwd
            ```
            > ![](https://i.imgur.com/5HnqCIp.png)
        :::

### 壓縮數據 - gzip

* 壓縮數據可以讓文件縮小佔有空間，而 Linux 中有多種壓縮數據的工具，可以根據需求做選擇

    | 工具 | suffix 文件擴展名 | 說明 |
    | - | - | - |
    | compress | .Z | Unix 最早期的壓縮工具 |
    | bzip2 (主要用於壓縮文字) | .bz2 | Burrow-Wheeler 塊排序文本壓縮算法、霍夫曼編碼 |
    | gzip | .gz | GNU 壓縮工具、Lempel-Ziv 編碼 |
    | zip | .zip | PKZIP 工具 Unix 實現 |

* `gzip` 是用來替代 `compress` 的免費版工具，gzip 相關工具如下

    | gzip 工具 | 說明 |
    | - | - |
    | gzip | 壓縮文件 |
    | zcat | 查看壓縮過的文件 |
    | gunzip | 解壓文件 |
    
    1. 壓縮檔案，並查看壓縮過後的檔案

        ```shell=
        ## 壓縮 file.txt 並輸出到 done.gz 檔
        gzip -c file.txt > done.gz

        ## 查看壓縮檔
        zcat done.gz
        ```
        :::info
        如果沒有另外指定 `-c` 操作符，則會將原來的檔案直接替換成壓縮檔案
        :::
        
        > ![](https://i.imgur.com/Iq3XNvP.png)

    2. 解壓檔案

        ```shell=
        gunzip -c done.gz > finishGunzip

        cat finishGunzip
        ```

        > ![](https://i.imgur.com/MV34YNY.png)

### 數據歸檔 - tar

* **歸檔** 與 **壓縮** 是兩種不同的行為；**歸檔是將多個檔案放置匯聚成一個檔案，壓縮則是將原來的數據透過特別的算法減少其佔用空間**

    > 這兩個行為常常會一起使用，所以會搞混是很正常的

* `tar` 命令最早上為了將數據寫到外部空間；格式如下

    > `tar` function [options] object1 object2 ...
    
    | tar's function | 說明 |
    | - | - |
    | -A | (--concatenate) 將已有的 tar 文件歸檔到另一個已有的 tar 文件 |
    | -r | (--append) 將數據追加到已有的 tar 文件 |
    | -c | (--create) 創建新的 tar 文件 |
    | -t | (--list) 列出歸檔內容 |
    | -u | (--update) 將已有的 tar 文件內的相同檔名的文件更新 |
    | -x | (--extract) 從已有的 tar 歸檔文件中提取文件 |

    | tar's options | 說明 |
    | - | - |
    | -C <\dir> | 切換到指定目錄 |
    | -f <\file> | 將壓縮結果輸出到指定檔案 |
    | -p | 保留所有文件的權限 |
    | -v | 顯示處理時的文件 |
    | -j | 將輸出內容重新定向給 bzip2 |
    | -z | 將輸出內容重新定向給 gzip |


    1. 歸檔文件

        ```shell=
        ## 將 .txt 結尾的檔案歸檔到 tarFinish.tar 檔案
        tar -cvf tarFinish.tar *.txt

        ls -laF
        ```
        > ![](https://i.imgur.com/zUSLPru.png)

    2. 查看歸檔後的文件列表

        ```shell=
        tar -tf tarFinish.tar
        ```
        > ![](https://i.imgur.com/OIfUHRy.png)

    3. 解壓文件

        ```shell=
        ## 解壓並輸出到指定資料夾中

        tar -xvf ./tarFinish.tar -C ./myExtract
        ```

        > ![](https://i.imgur.com/sBznkMC.png)

    :::success
    * **後綴 `.tgz` 文件**？
        
        `.tgz` 文件都是將 tar 檔案透過 gzip 算法壓縮過後的檔案，可以透過以下命令進行解壓並提取
        
        ```shell=
         tar -zxvf <filename.tgz>
        ```

        其實 suffix 結尾與 `.tar.gz` 相同，也可以使用兩段式命令解開
        
        ```shell=
        gunzip <filename.tar.gz>
        
        tar xvf <filename.tar>
        ```
    
    :::

## Appendix & FAQ

:::info
:::

###### tags: `Linux Shell`
