Scripting

如果命令連續多次失敗,則在 crontab 中發出警告

  • April 13, 2018

我的 crontab 中有一個命令來監控服務(具體來說,檢查我的網站的 Tor 版本是否仍然可以訪問):如果它可以訪問該站點,則此監控命令成功,否則失敗(並且我收到一封電子郵件)。然而,由於 Tor 的間歇性故障,我時不時地收到電子郵件,而且停機時間相當短。

如果我的 crontab 中的這個監控命令連續多次失敗(比如 10 次),我想收到通知,所以我只會在更長時間的中斷時收到通知。

當然,我可以編寫一個自定義腳本來執行此操作,將失敗次數儲存在臨時文件中等,但由於這看起來很常見,我認為可能已經存在一些標準解決方案(在同一moreutils ‘已經存在以服務chronic類似但不同的目的的方式。)

是否有一個包裝腳本,使得發行wrapper COMMAND將執行COMMAND並成功,除非最後 10 次呼叫COMMAND失敗,在這種情況下,它應該返回最後一個錯誤程式碼和失敗呼叫的輸出?

以下腳本可用作您描述的包裝器。它將給定命令的標準輸出和標準錯誤流保存到狀態目錄 ( $HOME/states) 並儲存失敗的執行次數。

如果命令執行失敗的次數超過 10(或命令行標誌的任何數量-t),它將提供一些輸出(在其標準錯誤流上)。在所有其他情況下,將不提供任何輸出。腳本以與給定命令相同的退出狀態退出。

範例使用:

$ sh ./script.sh -t 2 sh -c 'echo "this will fail"; cd /nowhere'
$ sh ./script.sh -t 2 sh -c 'echo "this will fail"; cd /nowhere'
FAILED 2 times: sh -c echo "this will fail"; cd /nowhere
f88eff95bba49f6dd35a2e5ba744718d
stdout --------------------
this will fail
stderr --------------------
sh: cd: /nowhere - No such file or directory
END

腳本本身(依賴於md5sumGNU coreutils):

#!/bin/sh

statedir="$HOME/states"

if ! mkdir -p "$statedir"; then
       printf 'Failed creating "%s"\n' "$statedir" >&2
       exit 1
fi

max_tries=10

while getopts 't:' opt; do
       case "$opt" in
               t) max_tries=$OPTARG ;;
               *) echo 'error' >&2
                  exit 1
       esac
done

shift "$(( OPTIND - 1 ))"

hash=$( printf '%s\n' "$@" | md5sum | cut -d ' ' -f 1 )

"$@" >"$statedir/$hash".out 2>"$statedir/$hash".err
code=$?

if [ -f "$statedir/$hash" ]; then
       read tries <"$statedir/$hash"
else
       tries=0
fi

if [ "$code" -eq 0 ]; then
       echo 0 >"$statedir/$hash"
       exit 0
fi

tries=$(( tries + 1 ))
printf '%d\n' "$tries" >"$statedir/$hash"

if [ "$tries" -ge "$max_tries" ]; then
       cat >&2 <<END_MESSAGE
FAILED $tries times: $@
stdout --------------------
$(cat "$statedir/$hash".out)
stderr --------------------
$(cat "$statedir/$hash".err)
END
END_MESSAGE
fi

exit "$code"

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