Scripting
如果命令連續多次失敗,則在 crontab 中發出警告
我的 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
腳本本身(依賴於
md5sum
GNU 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"