スクリプトパフォーマンスの向上[閉じる]

スクリプトパフォーマンスの向上[閉じる]

私はZabbix監視サービスの実行が停止したときに自動的に再起動するために使用できるスクリプトを開発してきました。私のスクリプトはうまくいきますが、改善できると思います。

#!/bin/bash
zabbix_server="service zabbix-server"
zabbix_agent="service zabbix-agent"
logfile=zabbix_auto_restart.log
logfilePath=/etc/scripts/zabbix/$logfile
zabbix_server_running=0
zabbix_agent_running=0

grep_agent (){
    local retval=$(ps -ef | grep -v grep | grep zabbix_agentd | wc -l)
    echo $retval
}

grep_server (){
    local retval=$(ps -ef | grep -v grep | grep zabbix_server | wc -l)
    echo $retval
}

check_zabbix_agentd (){
    if (( $(grep_agent) == 0 ))
    then
       $zabbix_agent start
       echo `date` "$zabbix_agent was stopped... Restarting" >> $logfile
       echo "************************************************" >> $logfile

       #Send email to notify that the script ran
       echo "$(date) $zabbix_agent was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <user email>

    else
       let zabbix_agent_running=1
    fi
}

check_zabbix_server (){
    if (( $(grep_server) == 0 ))
    then
       $zabbix_server start
       echo `date` "$zabbix_server was stopped... Restarting" >> $logfile
       echo "************************************************" >> $logfile

       #Send email to notify that the script ran
       echo "$(date) $zabbix_server was restarted from zabbix_restart.sh" | mutt -s "Zabbix Auto-restart Script Just Ran" <user email>

    else
       let zabbix_server_running=1
    fi
}

main_loop (){
    until ((zabbix_server_running == 1 && zabbix_agent_running == 1));
    do
        check_zabbix_agentd
        check_zabbix_server
        sleep 1.5
    done
}

main_loop

答え1

実際に間違っているのは、努力を複製することです。デフォルトでは、_agentハードコードされたすべての項目が発生したり、_server完全に重複しているように見えます。

たとえば、Linuxシステムで実行している場合は、これらのgrep_...()機能を完全に削除し、両方のcheck_...機能を1つのエンティティにマージできます。これは次のように機能します。

email(){ 
    mutt -s "Zabbix Auto-restart Script Just Ran" \<user email\>
}
prlog(){ 
    date +"%x %X:%tservice $1${2+%n************************}"
}
chk_run()
    while  [ "$#" -gt 0 ]
    do     if     ps -C zabbix_"$1"
           then   : "$(($1=1))"
           else   set zabbix_"$@"
                  service "$1" start || eval >&2 '
                  prlog   "$1 restart failed."  +; exit '"$?"
                  prlog   "$1 restarted."       +  >&2
                  prlog   "$1 restarted from $0." |email
           fi;    shift
    done

重要なことは、chk_runパラメータリストを使用して呼び出しを実行することです。各メンバーは、各反復について確認する必要があることを示します。

loop()
    until [ "$(($1&&$2))" -eq 1 ]
    do    chk_run "$@"
          sleep 2
    done  >/dev/null 2>>"$log"
agentd=0 server=0 loop agentd server

POSIXで変更する唯一のことはpsコマンドです。 POSIX は-Cスイッチを指定しないためです。したがって、ifこの行を次のように変更できます。

if    ps -eocomm= |
      grep -xqF zabbix_"$1"

最適化をmutt除いて、標準のコマンド言語でなければなりません。serviceps

標準構文の少なくとも1つの利点は、#!/bin/bashハッシュバンが完全に不要であることです。これには、一部のシェル固有の拡張用のアンカーがないため、POSIX 準拠を目指すすべてのシェルでほぼ同じでなければなりません。つまり、#!/bin/dashとても簡単です。(そしてうまくいくかもしれません)この場合は最適化してください。

もちろん、最適化されているかどうかにかかわらず、このスクリプトはほとんど常にsleep

私は定義することを拒否します$log。主にあなたがそれを定義する方法について話すことがないからです。そしてそれは大丈夫です。考えるもう定義しないでください。スクリプトの呼び出し環境を決定できる場合は、引数を渡す非常に簡単な方法になります。つまり、スクリプトが呼び出され、./scriptすでに実行可能である場合...

log=/dev/tty ./script

...呼び出し時に環境に値を設定します$log./script

/dev/tty出力ファイルを例として使用する理由は、十分に調整しながら起動する必要があると思うからです。ここにコードブロックを入れて./script上記のように実行すると、一部の出力ファイルではなくリアルタイムで端末に書き込まれるため、実際のログファイルにどのような内容が表示されるのかを明確に知ることができます。最後に、次のように呼び出します。

log=./real/logfile ./script

あるいは、ハイブリッドの動作ではなく、次のように表示されるようにスクリプトを変更することもできます2>>"$log"

2>>"${log:-/hardcoded/default/path/to/logfile}"

...この場合、シェルは$logまだ定義されていないハードコードされた値を使用します。これは次のことを意味します。

export log=/dev/tty; ./script
log=/dev/tty ./script

...引き続き端末にログファイルを記録します...

log= ./script
unset log; ./script

...ハードコードされたパスに書き込む...

./script

$log...現在のシェル環境にエクスポートするために、NULL以外の値がすでに存在するかどうかに応じて、ハードコードされたパスまたは別の場所に書き込まれます。

関連情報