從 crontab 轉發電子郵件的 POSIX(或攜帶式)方式
我有一個適用於 IRIX/Linux/macOS/FreeBSD 的安裝程序/更新程序腳本,我想將其兼容性擴展到 Solaris。
我已經修復了一些不符合 POSIX 的部分,除了
crontab
像這樣生成的部分:printf '%s\n' MAILTO=me@xyz.org '*/15 * * * * /path/cmd' | crontab -
# crontab -l # (on Linux/macOS/FreeBSD) MAILTO=me@xyz.org */15 * * * * /path/cmd
注意:
/path/cmd
除非檢測到問題,否則是安靜的程式碼在 Solaris 上失敗有以下三個原因:
MAILTO=
引發語法錯誤*/15
引發語法錯誤crontab -
嘗試打開名為-
我用以下方法修復了 #2和**#3**:
printf '%s\n' '0,15,30,45 * * * * /path/cmd' | crontab
# crontab -l 0,15,30,45 * * * * /path/cmd
現在我不知道如何轉換
MAILTO=
零件。從 POSIX 轉發電子郵件的方法是crontab
什麼?選擇的解決方法:
感謝*@ilkkachu和@Gilles’SO-stopbeingevil’*指針,這就是我決定以符合 POSIX的方式模擬crontab行為的方式:
MAILTO
# crontab -l 0,15,30,45 * * * * out=$(/path/cmd 2>&1); [ -n "$out" ] && printf \%s\\n "$out" | mailx -s "Cron <$LOGNAME@$(uname -n)>" me@xyz.org
但是,這個解決方案有一個潛在的問題:如果
printf
不是內置的 shell並且輸出太大,那麼它將失敗並出現類似的問題。Argument list too long
請注意,
MAILTO
即使在受支持的情況下,這對軟體安裝程序也沒有好處,因為它是一個全域設置:它將適用於 crontab 中的所有條目,而不僅僅是您的軟體添加的條目。如果您希望您的軟體將電子郵件發送到不同的地址,您需要在自己的程式碼中進行處理。這意味著您需要自己處理退出狀態和清空輸出的邏輯。
這是一些實現此邏輯的未經測試的程式碼。用空格替換換行符(或只是刪除它們)以將它們放在 crontab 文件中的單行上。
out=$(mktemp) && /path/cmd >"$out" 2>&1; status=$?; if [ "$status" -ne 0 ] || [ -s "$out" ]; then mailx -s "/path/cmd exited with status $status" me@example.org <"$out"; fi; rm -- "$out";
此程式碼僅使用 POSIX 功能以及廣泛可用的
mktemp
. 不幸的是,它在 IRIX 上不可用。如果 IRIX 有一個 POSIX 兼容的 m4,你可以用它來實現mktemp
. 作為備份,您可以將臨時文件儲存在使用者主目錄下的某個位置,或者儲存在只有其他人可以寫入的其他目錄中。不要在共享目錄中創建具有可預測名稱的臨時文件,例如/tmp
: that’s insecure。