在 terminal 下執行 shell script 時 尾巴夾上 最後面的 2>&1
在 Linux 的 Cron 排程中,/usr/local/bin/sys_checkman.sh 會執行。
這個 shell script 會把輸出寫入日誌檔。
在這個執行中,最後面的 2>&1 會將標準錯誤輸出導向到標準輸出。
這樣,正常輸出與錯誤訊息會一起寫入同一日誌檔。
日誌檔案的路徑是 /var/log/cron_checkman.log。
🔍 拆解它的運作原理
Linux 系統中有三個預設的標準資料流(稱為文件描述符,File Descriptors):
• 0:標準輸入(stdin),通常是鍵盤。
• 1:標準輸出(stdout),預設是螢幕,專門輸出正常的執行結果。
• 2:標準錯誤輸出(stderr),預設是螢幕,專門輸出錯誤訊息。
當你看到 >> /var/log/cron_monitor.log 2>&1 時,系統是這樣處理的:
1. >> /var/log/cron_monitor.log
這會把標準輸出
(1)以累加(append)的方式,導向到日誌檔中。此時錯誤訊息
(2)依然會跑到預設的地方(通常會變成一封信寄給系統管理員或 Cron 的擁有者)。
2. 2>
代表我要針對標準錯誤輸出(2)進行重新導向。
3. &1
& 在這裡是一個「參照」符號,意思是「前面指定的標準輸出(1)」。
如果沒加 &,變成 2>1,系統會誤以為你想把錯誤訊息寫進一個檔名叫作 1 的文字檔。
💡 在 shell script 的情境下,為什麼要這樣寫?
如果不加 2>&1:
• 當指令正常執行時,日誌會有記錄。
• 當指令發生錯誤(例如找不到路徑或權限不足)時,日誌檔會是一片空白,
因為錯誤訊息跑到別的地方去了,這會讓你非常難進行除錯(Debug)。
加上 2>&1 後,無論腳本執行是成功還是失敗,所有產生的訊息都會乖乖記錄在
/var/log/cron_checkman.log 裡,方便你一目了然。
補充資料:
1. > 和 >> 的差別 ?
在 Linux/Unix 的 Shell 環境中,> 和 >> 是處理資料流(I/O 重導向)的基本工具。
以下為您詳細說明兩者的差別,以及如何分離正常訊息與錯誤訊息。
這兩個符號最核心的差異在於處理舊資料的方式:
• >(覆蓋 / Overwrite):
如果目標檔案已經存在,它會先清空檔案內容,再寫入新資料。
• >>(累加 / Append):
如果目標檔案已經存在,它不會動舊資料,而是直接在檔案的最末端繼續追加新資料。
2. 如何把錯誤訊息和正常訊息分開寫入不同日誌檔
在 Shell 中,程式輸出的訊息主要分為兩種「資料流」,
各自有預設的代號(檔案描述符,File Descriptor):
• 1:標準輸出(stdout),指程式正常執行產生的訊息。通常省略不寫,單純寫 > 就等於 1>。
• 2:標準錯誤輸出(stderr),指程式發生錯誤或警告時產生的訊息。
# 示範語法
指令 1> 正常訊息.log 2> 錯誤訊息.log
(因為 1 可以省略,所以也可以寫成 指令 > 正常訊息.log 2> 錯誤訊息.log)
# Try 看看, 執行看看以下指令
ls /etc/hosts /不存在的資料夾 > info.log 2> error.log
# 結果預想
• info.log 會看到正常的查詢結果:/etc/hosts
• error.log 會看到錯誤訊息:ls: /不存在的資料夾: No such file or directory