跳至主要内容

訊息管理與重導

Linux 終端機就像是一個水管系統,資料會在不同的水管中流動。學會「訊息管理與重導」,就等於學會了如何切換與拼接這些水管,讓資料流向你想去的地方(例如存成檔案,或是交給下一個程式處理)。

1. 什麼是資料流重導向 (I/O Redirection)?

在 Linux 中,幾乎所有執行的程式都圍繞著三個標準的「資料流 (Data Stream)」運作。系統會分別配給它們三個代號(File Descriptor):

  • STDIN (Standard Input) - 代號 0:標準輸入。預設是你的「鍵盤」。
  • STDOUT (Standard Output) - 代號 1:標準輸出。程式執行成功的結果,預設會印在「螢幕」上。
  • STDERR (Standard Error) - 代號 2:標準錯誤。程式執行失敗或報錯的訊息,預設也是印在「螢幕」上。

2. 輸出重導向:>>>

當我們不想讓結果印在螢幕上,而是想把它「存起來」時,就會用到重導向符號。

  • > (覆寫輸出):將 STDOUT 導向到檔案。如果檔案已存在,會完全覆寫舊內容。
  • >> (附加輸出):將 STDOUT 導向到檔案結尾。如果檔案已存在,會接在原本的內容後面

實戰範例

# 將 hello 寫入檔案(如果沒有這個檔案會自動建立)
$ echo "hello" > test.txt

# 將 world 附加到檔案最後面
$ echo "world" >> test.txt

3. 進階錯誤處理:2>2>&1

預設情況下,> 只會捕捉代號 1 (STDOUT) 的成功訊息。如果你去搜尋一個沒有權限的資料夾,錯誤訊息 (STDERR) 還是會無情地漏到螢幕上!

實戰範例

# 刻意製造錯誤 (假設你不是 root)
$ ls /root > result.txt
ls: cannot open directory '/root': Permission denied
# ↑ 錯誤訊息依然印在螢幕上,且 result.txt 裡面是空的!

# 將錯誤訊息 (代號 2) 導向到 error.log
$ ls /root 2> error.log

# 🕳️ 黑洞大絕招:把不要的錯誤訊息直接丟進無底洞 (/dev/null)
$ ls /root 2> /dev/null

# 終極合體技:把成功 (1) 跟失敗 (2) 的訊息全都收進同一個檔案
$ ls /root > all_log.txt 2>&1
# (解讀:先把 STDOUT 導向到 txt,再把 STDERR(2) 導向到與 STDOUT(1) 相同的地方)

4. 管線命令:| (Pipe)

如果 > 是把水管接進水桶(存成檔案),那管線 | 就是把水管接上另一台濾水器。 它可以把「左邊指令的輸出 (STDOUT)」直接當作「右邊指令的輸入 (STDIN)」。

實戰範例

# 檢視系統上所有的程序,但只過濾出 nginx 相關的
$ ps aux | grep "nginx"

# 查閱超長日誌檔時,交給 less 來實現分頁翻看
$ cat /var/log/syslog | less

5. 雙向分流:tee (T 型水管接頭)

如果你單純使用 > (重導向),就像是把水管封死並接進了水桶。資料流進檔案後,你的螢幕上就什麼都看不到了,你只能事後再用 cat 打開檔案確認。

但如果你想要「一邊把結果存成檔案,一邊在螢幕上監看過程」該怎麼辦?這時候就要呼叫 tee

為什麼它叫 tee 呢?因為它的命名靈感就是水管工程裡的**「T 型三通接頭」**(長得就像英文字母 T)。 當資料流進這個 T 型接頭時,水流會被強制分成兩路:

  • 一路向下:流進你指定的檔案裡(存檔備份)。
  • 一路向右:繼續在管線中流動,也就是顯示在你的螢幕上(即時監看)。

實戰範例

# ❌ 如果只用 > :結果存進了檔案,但螢幕上一片空白,你不知道跑完了沒。
$ ip addr > ip_info.txt

# ✅ 如果改用 | tee :結果存進了檔案,同時你的螢幕也看得到完整的 IP 資訊!
$ ip addr | tee ip_info.txt

⚠️ 極度實用的避坑技巧:配合 sudo 寫入系統權限檔案 新手常犯的錯,是想要用 sudo echo "123" > /root/test.txt 來寫入需要特權的檔案,但這會顯示 Permission denied! 為什麼?因為 sudo 的特權只會賦予給前面的 echo,後面的 > 重導向依舊是你原本的普通帳號權限。

這時候 tee 就是完美的救星:

# 解法:把 123 交給有 sudo 特權的 tee 去寫入檔案。
# 結尾加上 > /dev/null 是為了把螢幕顯示的畫面丟進黑洞保持乾淨(依需求可省略)。
$ echo "123" | sudo tee /root/test.txt > /dev/null

🏢 實境演練:巨型日誌清查與健檢

情境背景: 老闆要求你寫一段指令,搜尋系統中所有超過 500MB 的龐大檔案。 條件:

  1. 必須將搜尋結果存成 big_files_report.txt
  2. 絕對不要把 Permission denied 的煩人報錯訊息印在螢幕或報告裡。
  3. 搜尋完成時,終端機畫面上要能同時看到搜尋結果,確保沒有做白工。

你的完美操作流程

# 結合 重導向黑洞、管線 與 tee 的終極連段技巧:
$ find / -type f -size +500M 2> /dev/null | tee big_files_report.txt

# 解讀:
# 1. 2> /dev/null 先把所有的權限不足報錯丟掉。
# 2. | 把成功的搜尋結果 (STDOUT) 往後傳。
# 3. tee 同時將結果印在螢幕上,並且存入 txt 檔案中。
進階延伸閱讀:Log 探勘與正規過濾

當你熟悉了重導向與管線命令後,想進一步學習如何使用 find -execgrep -vawk 在數十萬筆 Log 中撈取 DDoS 攻擊 IP 排行榜,請參閱: 👉 15-file-search-regex.md (🔍 尋找檔案與字串過濾:Log 探勘神技)