Shell

從 crontab 轉發電子郵件的 POSIX(或攜帶式)方式

  • April 8, 2022

我有一個適用於 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 上失敗有以下三個原因:

  1. MAILTO=引發語法錯誤
  2. */15引發語法錯誤
  3. 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

引用自:https://unix.stackexchange.com/questions/697476