stdin / stdout / stderr
每個程序有三個預設的 I/O stream:
- stdin(0):輸入,預設來自鍵盤
- stdout(1):正常輸出,預設輸出到 terminal
- stderr(2):錯誤輸出,預設也輸出到 terminal(但可以分開重定向)
# 把 stdout 重定向到檔案
ls > files.txt # 覆蓋
ls >> files.txt # 追加
# 把 stderr 重定向
command 2> error.log
# stdout 和 stderr 都重定向
command > output.log 2>&1
# 丟棄(不顯示、不保存)
command 2>/dev/nullPipe(|):把上一個程序的輸出當成下一個的輸入
# 找 log 裡的 error,再排序,再計數唯一
cat app.log | grep "ERROR" | sort | uniq -c | sort -rn | head -10
# 解讀:
# cat app.log → 輸出整個 log
# grep "ERROR" → 只留包含 ERROR 的行
# sort → 排序(uniq 要求相同的行相鄰)
# uniq -c → 計算每種 error 出現幾次
# sort -rn → 按數字倒序(最多的在前)
# head -10 → 只看前 10Pipe 讓你不需要中間檔案就能組合多個工具的功能。
sed:串流文字替換
# 替換
sed 's/old/new/g' file.txt # 替換所有 old → new
sed -i 's/localhost/prod.db/g' config.yml # -i 直接修改檔案
# 刪除包含 pattern 的行
sed '/DEBUG/d' app.log
# 只顯示某幾行
sed -n '5,10p' file.txt # 顯示第 5-10 行awk:按欄位處理文字
# 預設欄位分隔符是空格
# $1 是第一欄,$2 是第二欄,$NF 是最後一欄
# 顯示第 1 和第 3 欄
awk '{print $1, $3}' data.txt
# 以 : 分隔(/etc/passwd 格式)
awk -F: '{print $1}' /etc/passwd # 列出所有用戶名
# 計算第二欄的總和
awk '{sum += $2} END {print sum}' data.txt
# 過濾:只印第三欄 > 100 的行
awk '$3 > 100 {print $0}' data.txt基本 Shell Script
#!/bin/bash
# 第一行是 shebang,告訴 OS 用什麼解釋器
set -e # 任何指令失敗就退出(避免後續錯誤被忽略)
# 變數
NAME="World"
echo "Hello, $NAME!"
# 條件
if [ -f "./config.yml" ]; then
echo "Config exists"
else
echo "Config missing!"
exit 1
fi
# 迴圈
for FILE in *.log; do
echo "Processing $FILE"
wc -l "$FILE"
done
# 函式
backup_logs() {
local dir=$1 # 局部變數
tar -czf "backup_$(date +%Y%m%d).tar.gz" "$dir"
}
backup_logs ./logs執行 shell script:
chmod +x script.sh # 加執行權限
./script.sh # 執行一行常用組合
# 找最大的 10 個檔案
find . -type f -exec du -h {} + | sort -rh | head -10
# 殺掉特定 port 的 process
lsof -ti:3000 | xargs kill -9
# 即時監控 HTTP log 的 status code 分佈
tail -f access.log | awk '{print $9}' | sort | uniq -c | sort -rnShell scripting 的深度很深,但這些基礎讓你能在 CI/CD 腳本、部署腳本、log 分析裡靈活操作。需要複雜邏輯時,Python 更適合——Shell 的強項是快速的文字處理和指令組合。