tee 是 Linux 管道操作中的「三通閥」:它從標準輸入讀取資料,同時寫入標準輸出與一個或多個檔案。掌握 tee 能讓你在終端機即時觀察輸出的同時,完整保存日誌、除錯資料或建立多份備份。
tee [選項] [檔案...]
| 參數 | 長選項 | 說明 |
|---|---|---|
| -a | --append | 附加模式:不覆蓋現有檔案,資料寫入檔案末尾 |
| -i | --ignore-interrupts | 忽略中斷訊號 (SIGINT,即 Ctrl+C) |
| --help | 顯示說明 | |
| --version | 顯示版本資訊 |
ls -la | tee filelist.txt
終端機顯示目錄列表,同時完整寫入 filelist.txt。
echo "第一次執行" | tee -a log.txt
echo "第二次執行" | tee -a log.txt
log.txt 將包含兩行內容,不會被覆蓋。
cat important.log | tee backup1.txt backup2.txt backup3.txt
一份輸入同時存成三份備份,tee 也會輸出到螢幕。
echo "hello" | tee - - -
輸出三行 hello 到終端機。搭配 echo -n 可在同一行重複輸出。
tee 預設只處理標準輸出 (stdout)。要同時捕獲錯誤輸出,需先將 stderr 重導向至 stdout:
# 正確寫法:先合併流再交給 tee
ls /notexist 2>&1 | tee error.log
# 錯誤寫法:管道只傳遞 stdout
ls /notexist | tee error.log # error.log 會是空的
tee myinput.txt
# 輸入內容,每行 Enter 確認
# Ctrl+D (EOF) 結束輸入
輸入的每一行即時顯示於螢幕並寫入檔案。加上 -i 可防止 Ctrl+C 中斷,只能用 Ctrl+D 結束。
#!/bin/bash
exec > >(tee -a /var/log/myscript.log) 2>&1
echo "腳本啟動 $(date)"
# ... 其餘腳本邏輯
./step1.sh
./step2.sh
echo "腳本結束 $(date)"
使用進程替換 >() 讓整個腳本的輸出 (含 stderr) 自動分流到日誌檔與終端機。
echo "new config line" | sudo tee -a /etc/nginx/nginx.conf > /dev/null
sudo tee 以 root 權限寫檔,> /dev/null 抑制螢幕輸出。這是唯一不需開啟 root shell 就能以管道方式寫入系統檔案的標準做法。
mysqldump db_name | tee backup_$(date +%F).sql | gzip > backup_$(date +%F).sql.gz
同時產生未壓縮備份 (供快速檢視) 與壓縮備份 (供長期存儲)。
tail -f /var/log/nginx/access.log | tee -a /var/log/nginx/access_mirror.log | grep --line-buffered " 50[0-9] " | while read line; do
alert_system "$line"
done
tee 建立日誌鏡像,grep 即時過濾 5xx 錯誤觸發告警,三者並行不悖。
stdbuf -oL -eL 或 unbuffer 強制行緩衝。tee 本身不提升權限,寫入受保護檔案需搭配 sudo。tee 需同時寫入多個檔案描述符,超大資料流可能成為 I/O 瓶頸,考慮改用 split 或平行處理。| 操作 | 螢幕顯示 | 存檔 | 多檔同時寫入 | 追加模式 |
|---|---|---|---|---|
cmd > file | 否 | 是 (覆蓋) | 否 | >> |
cmd | tee file | 是 | 是 (覆蓋) | 是 | -a |
cmd | tee -a file | 是 | 是 (追加) | 是 | 內建 |
cmd 2>&1 | tee file | 是 | 是 (含錯誤) | 是 | -a |
tee 是 Linux 管道哲學「做一件事並做好」的經典體現。熟練運用它能讓日常運維、腳本開發、除錯排查事半功倍。