腳本與 crontab 中常見 >/dev/null 2>&1,後半段 2>&1 究竟在做什麼?為何順序不能顛倒?本文從檔案描述符原理切入,配合實測說明。
| 代號 | 名稱 | 預設指向 |
|---|---|---|
| 0 | stdin(標準輸入) | 鍵盤/終端 |
| 1 | stdout(標準輸出) | 螢幕/終端 |
| 2 | stderr(標準錯誤) | 螢幕/終端 |
2>&1 將檔案描述符 2(stderr)複製導向至檔案描述符 1(stdout)目前所指向的目標。
測試腳本 t.sh:
#!/usr/bin/zsh tttttt # 不存在的指令,產生 stderr echo "test" # 正常輸出 stdout
| 指令 | 結果說明 |
|---|---|
./t.sh >/dev/null 2>&1 | stdout → /dev/null,stderr 複製 stdout 也 → /dev/null (全靜默) |
./t.sh 2>&1 >/dev/null | stderr 複製 stdout(目前指向終端),再將 stdout → /dev/null (stderr 仍輸出終端) |
$ ./t.sh ./t.sh:2: command not found: tttttt test $ ./t.sh >/dev/null ./t.sh:2: command not found: tttttt $ ./t.sh >/dev/null 2>&1 (無輸出) $ ./t.sh 2>&1 >/dev/null ./t.sh:2: command not found: tttttt test
>file 2>&1 先綁定 stdout,stderr 再跟隨。2>&1 >file 先綁定 stderr 到舊 stdout,stdout 才改向 file,stderr 不受影響。記住:「先導標準輸出,再合併標準錯誤」才能達到雙重導向靜默的效果。