掌握 Linux 標準流(Standard Streams)與重導向機制,是 Shell 腳本開發、系統運維與命令列高效操作的核心技能。本文系統講解標準輸入、標準輸出、標準錯誤的概念、檔案描述符、重導向語法與實戰技巧,並提供豐富範例助您融會貫通。
| 流名稱 | 檔案描述符 | 預設連接 | 典型用途 |
|---|---|---|---|
| 標準輸入 | 0 | 鍵盤/終端機 | 程式讀取輸入資料 |
| 標準輸出 | 1 | 螢幕/終端機 | 程式正常執行結果輸出 |
| 標準錯誤 | 2 | 螢幕/終端機 | 錯誤訊息、診斷資訊輸出 |
Linux 設計哲學:「一切皆檔案」,標準流本質上是進程打開的特殊檔案描述符,可像操作普通檔案一樣重導向。
command > file # 覆蓋寫入(截斷檔案)
command 1> file # 同義,明確指定 fd 1
command >> file # 追加寫入(不截斷)
command 1>> file # 同義
# 將 echo 輸出導向檔案,螢幕無輸出
echo "Hello World" > output.txt
# 查看檔案內容
cat output.txt
# Hello World
# 追加模式
echo "Line 1" > log.txt
echo "Line 2" >> log.txt
cat log.txt
# Line 1
# Line 2
command < file # 從檔案讀取標準輸入
command 0< file # 同義
# 統計 /etc/passwd 行數(wc -l 從 stdin 讀取)
wc -l < /etc/passwd
# 等同於
cat /etc/passwd | wc -l
command 2> file # 錯誤導向檔案(覆蓋)
command 2>> file # 錯誤導向檔案(追加)
command 2>&1 # stderr 重導向到 stdout(合併輸出)
# 只捕獲錯誤訊息
ls /nonexistent 2> errors.txt
# 正常輸出與錯誤分離存檔
find / -name "*.conf" 1> found.txt 2> errors.txt
# 合併輸出到同一檔案
find / -name "*.conf" > all.txt 2>&1
# 或簡寫(Bash 4+)
find / -name "*.conf" >& all.txt
# 從 input.txt 讀取,結果寫入 output.txt
cat < input.txt > output.txt
# 順序不影響結果
cat > output.txt < input.txt
cat > script.sh << 'EOF'
#!/bin/bash
echo "Hello, World!"
echo "Today is $(date)"
EOF
# 使用 'EOF' 防止變數展開;若用 EOF 則會展開變數
# 執行結果:
# Hello, World!
# Today is Mon Dec 30 10:30:00 CST 2024
# 直接將字串作為 stdin 傳給命令
read var <<< "Hello World"
echo $var # Hello World
# 只看錯誤,丟棄正常輸出
command > /dev/null
# 只看正常輸出,丟棄錯誤
command 2> /dev/null
# 完全靜默(常用於腳本靜默執行)
command > /dev/null 2>&1
# 或
command >/dev/null 2>&1
# 開啟 fd 3 寫入檔案
exec 3> custom.log
echo "Custom log" >&3
exec 3>&- # 關閉 fd 3
# 開啟 fd 4 讀取檔案
exec 4< input.txt
read line <&4
exec 4<&-
# 交換 stdout 和 stderr
command 3>&1 1>&2 2>&3 3>&-
# 現在 stdout 輸出原 stderr 內容,stderr 輸出原 stdout 內容
| 需求 | 命令範例 |
|---|---|
| 腳本靜默執行,記錄錯誤到日誌 | ./script.sh >/dev/null 2>&1 | tee -a error.log |
| 同時顯示螢幕並存檔 | command 2>&1 | tee output.log |
| 捕獲命令退出碼與輸出 | output=$(command 2>&1); ret=$? |
| 管道中只傳遞 stdout,stderr 仍顯示 | command 2>&1 | grep "pattern" |
| 忽略所有輸出 | command >/dev/null 2>&1 |
| 將 stderr 導向 stdout 再管道處理 | command 2>&1 | less |
Linux 重導向機制的核心在於檔案描述符的操控。熟練掌握 0, 1, 2 三大標準流與 >, >>, <, 2>&1, >&, <<, <<< 等操作符,能讓您靈活控制資料流向,編寫健壯、高效的 Shell 腳本。建議在終端機實際操練上述範例,建立肌肉記憶,將重導向技巧內化為直覺工具。