# 那些你不能不會的 Linux 基礎指令!(下)
[TOC]
感謝您點進本篇文章,我是 LukeTseng,近期接觸到 Linux 系統,時常需要面對黑色終端機,有些時候想做到一些操作,卻也不知道那個指令叫什麼,我也沒有好好奠基 Linux 的基礎指令,所以特此製作本篇文章!希望能解決到你我的痛點!
若本篇文章某處有誤,敬請告知,感謝!
## 萬用字元(Wildcard)
最常見的就是 `*` 跟 `?` 這兩個字元。
`*` 代表「任意長度的任意字元」,可以是 0 個、1 個或多個字元。
範例如下:
- `ls *`:列出目前目錄下所有非隱藏檔案。
以下是 `ls *` 跟 `ls` 的差別:

- `ls *.txt`:列出所有副檔名為 `.txt` 的檔案(如 `a.txt`、`b.txt`)。

- `ls a*`:列出所有以 `a` 開頭的檔案(如 `apple`、`a.txt`)。

- `ls *a*`:列出所有檔名裡面有包含 `a` 這個字元的檔案。
下圖中使用 `ls *a*` 就找到 `abcdefg`、`alphafile` ... 以及 snap 目錄底下的 `firmware-updater` 跟 `snapd-desktop-integration` 檔案。

---
`?` 代表「任意一個字元」,只能匹配一個字元。
如:
- `ls ?.txt`:列出所有檔名只有一個字元且副檔名為 `.txt` 的檔案(如 `a.txt`、`b.txt`)。
像以下的 `ab.txt` 就沒有被印出來,但 `a.txt`、`b.txt` 是有的,因為 `?` 只匹配單一一個字元而已,除非你再多加一個 `?` 字元,如下面第二張圖。

以下這張圖再多加一個 `?`,變成 `ls ??.txt`,結果只會顯示一個檔案 `ab.txt`,因為 `a.txt` 跟 `b.txt` 的檔名沒有恰含有兩個的字元。

- `ls file?.txt`:列出像 `file1.txt`、`fileA.txt` 這種檔案,但不會匹配到 `file10.txt`。
以下不會顯示 `file100.txt` 跟 `file10.txt` 檔案。

其他範例:
- `rm *.png`:刪除所有副檔名為 `.png` 的檔案。
- `cp file?.txt backup/`:複製所有像 `file1.txt`、`fileA.txt` 這類檔案到 `backup` 目錄。
---
有關這個萬用字元,以下有幾個注意事項:
- `*` 和 `?` 不會匹配以 `.` 開頭的隱藏檔案,除非明確指定。
- 若要讓這些符號失去特殊意義(像是真的要找檔名有 `*` 或 `?`),可用反斜線 `\` 做為跳脫字元,例如 `ls \*`。
## 搜尋類型指令
### which
`which` 是 Linux 中用於查找可執行檔(`.exe`)路徑的工具,會根據環境變數 PATH 的設定,搜尋並顯示指令的完整路徑。
基本語法:
```bash
which [options] executable_file
```
常用參數:
- `-a` 或 `--all` 選項可以列出 PATH 中所有匹配的指令。
- `-V` 或 `--version` 選項用於顯示版本資訊。
相關範例:
- 查找 bash 執行檔在哪裡:`which bash`
- 結果:`/usr/bin/bash`
- 查找多個路徑:`which -a python3`
```bash
/usr/bin/python3
/bin/python3
```
### find
`find` 顧名思義就是拿來搜尋某個檔案用的。
基本語法:
```
find [path] [options] [condition]
```
會在 path 路徑當中,尋找符合 condition(條件)的檔案。
#### 依檔名搜尋
使用 `-name` 參數。
`find . -name abc.txt` 會在當前目錄下找尋檔案名稱為 `abc.txt` 的檔案。
若要不區分大小寫,可以使用 `-iname` 參數,如:`find /home -iname abc.txt`。
檔名中可以使用萬用字元 `*`,如:`find ./ -name "*foo*"` 會找出包含 `"foo"` 關鍵字的所有檔案。
以下是 `find . -iname "file*.txt"` 的範例示圖,會在當前目錄(`.`)中尋找所有 `file` 開頭的 `.txt` 檔案。

#### 依檔案型態搜尋
使用 `-type` 參數。
- `-type f` 表示只搜尋一般檔案。
- `-type d` 表示只搜尋目錄。
而上述其他可用的類型還包括:`l`(符號連結)、`b`(區塊裝置)、`c`(字元裝置)、`p`(管道)、`s`(socket)。
範例:
- `find ./ -name "*foo*" -type f` 會找出檔名包含 `"foo"` 的所有檔案。
#### 依檔案大小搜尋
使用 `-size` 參數,`+` 表示大於、`-` 表示小於,如 `find ./ -size +500M` 會找出所有大於 500 MB 的檔案。
常用單位:
- c(bytes)
- k(Kilobytes)
- M(Megabytes)
- G(Gigabytes)
範例:
- `find ./ -name "*.jpg" -size -160k -delete` ,找出並刪除 < 160k 的 .jpg 照片。
#### 依時間搜尋
- `-mtime`、`-mmin` 參數搜尋檔案的「修改」時間(天和分鐘)
- `-ctime` 和 `-cmin` 參數分別搜尋檔案的「建立」時間(天和分鐘)
- `-atime` 和 `-amin` 參數分別搜尋檔案的「最後開啟」時間(天和分鐘)
範例:
- `find ./ -type f -mmin -5` 會找出 < 5 分鐘以內變動過的所有檔案。
- `find ./ -mtime -3` 找出 < 3 天內修改的檔案。
- `find ./ -mtime +3` 則是找出 > 3 天前修改的檔案。
#### 實際應用
像是你想要清理系統中超過 7 天沒有使用的暫存檔,可用:`find /tmp -type f -atime +7 -delete`
## 字串處理指令
### cat
`cat` 是來自英文 concatenate 中取 `cat` 的縮寫,用來一次性顯示檔案內容、合併檔案,或建立新檔案的指令。
用法:
- `cat file_name`:顯示整個檔案內容。
- `cat file1 file2 > newfile`:合併 `file1` 和 `file2`,輸出到 `newfile`。
- `cat > newfile`:從鍵盤輸入內容,Ctrl+D 結束並儲存。
裡面的 `>` 符號表示輸出重新導向(Output Redirection)的意思,用於將指令的執行結果輸出到檔案中,而非顯示在終端機上。
常用參數:
- `-n`:顯示行號。
- `-b`:只對非空行編號。
- `-s`:壓縮多個空行為一行。
範例:
```bash
cat test.txt
cat file1.txt file2.txt > merged.txt
cat -n test.txt
```
以下是 `cat test.txt` 的範例圖,會從 `test.txt` 擷取所有文字,並輸出在終端機上面。

以下是 `cat file1.txt file2.txt > merged.txt` 的範例圖,由於原本 `cat` 會將文檔內容輸出在終端機上嘛,所以透過 `>` 可以將輸出的內容輸出到某個檔案上面。

以下是 `cat -n test.txt` 的範例圖,加上 `-n` 參數可以顯示行數。

### more
`more` 與 `cat` 是類似的東西,另外 `more` 也沒有什麼英文縮寫,`more` 就是 `more`。而他跟 cat 的差別在於 `more` 可以分頁顯示檔案內容,適合查看大型檔案。
用法:`more file_name`。
常用操作:
- 空白鍵:下一頁。
- Enter:下一行。
- `/string`:搜尋字串,其中 `string` 是要拿來填寫的字串。
- `q`:退出。
- `v`:進入 vi 編輯器。
以下是 `more bbc_new.txt` 的範例,內容均擷取自新聞:https://www.bbc.com/news/articles/c87400e3j5eo

出現 `--More--(24%)` 的訊息可以按下空白鍵往下一頁:

### grep
`grep` 是取自英文 global regular expression print 的縮寫,是用來搜尋檔案中符合條件的字串,當中支援正規運算式(Regex:regular expression)。
用法:
- `grep 'string' file_name`:搜尋檔案中包含指定字串的行。
- 常結合 `cat` 跟管道(pipe)符號:`cat file_name | grep 'string'`。
管道符號是 `|`,在鍵盤的 `]` 右中括號的右邊,也寫著反斜線的符號,`shift + \` 就可以打出來。
管道符號(`|`)是 Linux 中將一個指令的輸出直接傳遞給另一個指令作為輸入的特殊符號,所以可以看到 `cat file_name | grep 'string'` 的地方,`grep` 後面就不需要再加上 `file_name` 了,因為前面 `cat file_name` 就當成是他的輸入。
grep 常用參數:
- `-i`:忽略大小寫。
- `-v`:反向選取,不包含字串的行。
- `-n`:顯示行號。
- `-w`:精確匹配整個字。
- `-r`:遞迴搜尋目錄。
- `-A N`:顯示匹配行及後 N 行。
- `-B N`:顯示匹配行及前 N 行。
- `-C N`:顯示匹配行及前後 N 行。
相關範例:
- `grep 'root' /etc/passwd`
使用 `grep` 會找出相對應的字串,找到的話會顯示紅字,白字為符合條件字串所在的行。

- `grep -i 'error' log.txt`
`-i` 為不分大小寫。`grep` 可以在大量的詞海裡面找出相對應的字串,非常方便。

- `grep -n 'main' *.c`
`-n` 參數為字串所在顯示行數,以下動作就在 `.c` 檔案中要找到 `main` 字串,顯示於 `a.c` 檔案中的第三行。

- `cat test.txt | grep 'hello'`
結合管道符號來做字串過濾的範例如下。
從 `cat test.txt` 輸出的內容傳遞給 `grep` 作為輸入的參數做使用,效果等同於 `grep 'hello' test.txt`

### head
`head` 指令是 Linux 中用來顯示檔案「前幾行」內容的工具。
`head` 預設顯示檔案的前 10 行,如:`head filename.txt` 會印出 filename.txt 的前 10 行。
若要指定行數可這樣寫:`head -n 5 filename.txt`,或簡寫 `head -5 filename.txt`。
也可顯示多個檔案的開頭內容:`head file1.txt file2.txt`。
顯示前 N 個位元組(bytes):`head -c 20 filename.txt`,顯示前 20 個 bytes。
### tail
有 `head` 就會有 `tail`,`tail` 可顯示文字檔的後幾行內容,預設是顯示後十行的內容。
使用方法與 `head` 相同。
### wc
`wc` 可不是廁所哦XD,`wc` 的英文全名是 word count,在 Linux 中用來統計檔案內容的行數、字數、字元數、位元組數等的基本指令。
功能:
- 計算行數(lines)
- 計算字數(words)
- 計算字元數(characters)
- 計算位元組數(bytes)
語法:
```
wc [options] file_name
```
若不指定檔案,`wc` 會從標準輸入讀取資料。
常用參數:
- `-l`:只顯示行數。
- `-w`:只顯示字數。
- `-c`:只顯示 byte 數。
- `-m`:只顯示字元數。
- `-L`:顯示最長行的長度。
相關範例:
- `wc test.txt`,計算檔案的行數、字數、位元組數。
輸出格式:`行數 字數 位元組數 檔案名`

- `wc -l test.txt` 只顯示行數。

- `wc -w test.txt` 只計算字數。
- `wc -c test.txt` 只顯示字元數。
- `grep 'error' log.txt | wc -l`,統計 `log.txt` 中包含 `"error"` 的行數。
## 重新導向(redirect)工具
`>`、`<`、`>>` 這三個符號都是在 Linux 中做重新導向的工具,可以將指令的輸出或輸入改變方向。
### >
`>` 大於符號為輸出重導向(覆蓋),功能是將指令的「標準輸出」(stdout)寫入指定檔案,覆蓋原有內容。
範例:`cat test.txt > result.txt`
上面的指令會把 `test.txt` 的內容寫到 `result.txt`,原本的 `result.txt` 會被覆蓋(`result.txt` 會被清空,然後再把 `test.txt` 的文本輸出到 `result.txt` 上面去)。
下圖展示了這個指令使用前後的效果:

### >>
這個指令也是輸出重導向,但是跟 `>` 不同的是,`>>` 會追加在文檔後面,而非直接覆蓋掉所有內容。
範例:`cat test.txt >> result.txt`
下圖展示了這個指令使用前後的效果:

### <
`<` 是輸入重導向,用於將檔案內容作為指令的「標準輸入」(stdin)來源,取代原本的鍵盤輸入。
範例:`cat < test.txt`
這個指令等同於 `cat test.txt`,因為 `<` 就是在讀取檔案內容。
下圖展示了指令的使用效果:

## Linux 版工作管理員
### ps
首先介紹 ps 指令,ps 的全名是 process status,用來顯示目前系統中正在執行的程序(process)狀態。類似 Windows 的工作管理員,可以讓你查詢系統上所有或特的程序資訊,包括程序 ID、使用者、資源佔用、啟動時間等。
若單一輸入 `ps` 指令,只會顯示「目前這個終端機」下執行的程序,不包含其他使用者或背景服務。輸出通常包含欄位:
- PID(程序 ID)
- TTY(終端機)
- TIME(CPU 使用時間)
- CMD(指令名稱)

### ps aux
`ps aux` 這一串指令是最常用的程序查詢組合之一,能夠列出所有 user 的所有程序,並顯示詳細資訊。這個組合的三個選項分別代表:
- `a`:顯示所有使用者的程序(不只自己的)
- `u`:以「使用者為主」的格式顯示,包含 `USER`、`%CPU`、`%MEM` 等欄位
- `x`:顯示沒有控制終端機(TTY)的程序(例如系統服務)
輸入 `ps aux` 可能會出現以下畫面:

### 結合 grep 過濾特定條件
範例指令:`ps aux | grep root`。
輸入後會呈現下圖資訊,會從 `ps aux` 中找出所有 `root` 的程序:

## 總整理
### 萬用字元(Wildcard)
星號(`*`)代表任意長度的任意字元(包括零個),如
- `ls *.txt` 列出所有 `.txt` 檔案。
- `ls *a*` 找出檔名包含字母 `a` 的所有檔案。
問號(`?`)只匹配單一字元,如
- `ls ?.txt` 只列出檔名為一個字元的 `.txt` 檔案(如 `a.txt`)
- `ls ??.txt` 則列出檔名恰好兩個字元的檔案(如 `ab.txt`)。
萬用字元不會匹配以點(`.`)開頭的隱藏檔案,除非明確指定,若要搜尋檔名真的包含 `*` 或 `?` 符號,需使用反斜線 `\` 做跳脫字元。
### 搜尋類型指令
- `which` 指令用於查找可執行檔的完整路徑,根據環境變數 PATH 進行搜尋,
- 範例:`which bash` 會顯示 `/usr/bin/bash`,加上 `-a` 參數可列出所有匹配的路徑。
- `find` 可依檔名(`-name`)、檔案類型(`-type`)、大小(`-size`)、時間(`-mtime`、`-ctime`、`-atime`)等條件搜尋檔案。
- 範例:`find . -name "*.txt"` 找出當前目錄下所有 `.txt` 檔案。
### 字串處理指令
- `cat` 指令源自 concatenate,用於顯示檔案內容或合併檔案。
- 範例:`cat file1.txt file2.txt > merged.txt` 將兩個檔案合併輸出給 `merged.txt`
- `cat -n test.txt` 顯示行號。
- `more` 指令用於分頁顯示大型檔案,按空白鍵翻頁,按 Enter 往下一行,輸入 `/string` 可搜尋字串,按 q 退出。
- `grep` 指令是 global regular expression print 的縮寫,用於搜尋檔案中符合條件的字串,支援正規運算式。
- 常用參數:
- `-i`(忽略大小寫)
- `-n`(顯示行號)
- `-v`(反向選取)
- `-r`(遞迴搜尋)
- grep 常結合管道符號(`|`)使用,如 `cat test.txt | grep 'hello'` 等同於 `grep 'hello' test.txt`。
- `head`、`tail` 指令分別顯示前幾行跟後幾行的文字,`-n numbers` 可以調整要顯示的行數。
- `wc` 全名為 word count,計算用來統計檔案內容的行數、字數、字元數、位元組數。
### 重新導向工具
- 大於符號(`>`)將指令輸出寫入檔案並覆蓋原有內容,如 `cat test.txt > result.txt`。
- 雙大於符號(`>>`)將輸出追加到檔案末端而不覆蓋,如 `cat test.txt >> result.txt`。
- 小於符號(`<`)將檔案內容作為指令的輸入來源,`cat < test.txt` 等同於 `cat test.txt`。
### 程序管理工具
`ps` 指令全名為 process status,用於顯示系統中正在執行的程序狀態,類似 Windows 工作管理員。
單獨輸入 `ps` 只顯示當前終端機下的程序,含 PID(程序 ID)、TTY(終端機)、TIME(CPU 使用時間)、CMD(指令名稱)等欄位。
`ps aux` 指令是最常用的組合,列出所有使用者的所有程序及詳細資訊。其中 `a` 顯示所有使用者的程序,`u` 以使用者格式顯示(包含 `USER`、`%CPU`、`%MEM` 等欄位),`x` 顯示沒有控制終端機的程序(如系統服務)。
結合 `grep` 可過濾特定條件,如 `ps aux | grep root` 找出所有 `root` 使用者的程序。
## 參考資料
[【Linux】一步一步学Linux——which命令(45)_linux which命令详解-CSDN博客](https://blog.csdn.net/dengjin20104042056/article/details/96118987)
[Linux which 指令](https://www.hy-star.com.tw/tech/linux/comm/which.html)
[Unix/Linux 的 find 指令使用教學、技巧與範例整理 – G. T. Wang](https://blog.gtwang.org/linux/unix-linux-find-command-examples/)
[在 Linux 下使用 find 指令查詢目錄與檔案的速查筆記 | The Will Will Web](https://blog.miniasp.com/post/2010/08/27/Linux-find-command-tips-and-notice)
[Day17-wildcard 萬用字元(一) - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10223904)
[Linux常用命令:find、grep、vim、cat、less、more_less和vim-CSDN博客](https://blog.csdn.net/wszzr999/article/details/130879142)
[Linux系统介绍(五)常用命令 - 窗外蟋蟀博客](https://keysaim.github.io/post/linux/2017-11-17-linux-study-common-tools/)
[linux >和>>的区别,<号使用_linux >>-CSDN博客](https://blog.csdn.net/wenxuechaozhe/article/details/52564394)
[Linux常用指令之——ps aux-CSDN博客](https://blog.csdn.net/weixin_42338901/article/details/130846988)
[鳥哥私房菜 - 第 5 堂課:權限應用、程序之觀察與基本管理](https://linux.vbird.org/linux_basic_train/centos8/unit05.php)